Binding does not update usercontrol property correctly MVVM

Edit: old code removed

I put it in my MainWindow.xaml

 <SpinTextBlock:SpinTextBlock Text="{Binding Path=DataContext.WelcomeTitle, ElementName=Window,UpdateSourceTrigger=PropertyChanged}" Height="60" Width="40" x:Name="TextBlock"/>

      

And bind it to a property in MainViewModel.cs

        public string WelcomeTitle
    {
        get
        {
            return _welcomeTitle;
        }

        set
        {
            if (_welcomeTitle == value)
            {
                return;
            }

            _welcomeTitle = value;
            RaisePropertyChanged(WelcomeTitle);
            Dispatcher.CurrentDispatcher.BeginInvoke(
new Action<String>(RaisePropertyChanged),
DispatcherPriority.DataBind, "WelcomeTitle");
        }
    }

      

Everything works fine except that the Text property in my UserControl is not updated when the value in the ViewModel is updated. Instead, the update from the ViewModel is directly pushed to the TextBlock (to the UserControl) and to the storyboard, and all the properties of my usercontrol are not called at all.

Anyone got a solution?

EDIT WORKING SOLUTION

Usercontrol code coding. Listened to the property changes to start my storyboards and update the properties.

    public partial class SpinTextBlock : INotifyPropertyChanged 
{
    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(SpinTextBlock), new FrameworkPropertyMetadata(
 string.Empty,
 new PropertyChangedCallback(OnTextPropertyChanged)));

    private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        SpinTextBlock obj = d as SpinTextBlock;
        obj.OnTextChanged(e.NewValue as string);

    }

    private  void OnTextChanged(string newValue)
    {
        UpdateTextBlocks(newValue);
    }

    public static readonly DependencyProperty TextOldProperty =
      DependencyProperty.Register("TextOld", typeof(string), typeof(SpinTextBlock), new PropertyMetadata(default(string)));

    public string Text
    {
        get
        {
            return (string)GetValue(TextProperty);
        }
        set
        {
            SetValue(TextProperty, value);
        }
    }

    private string TextOld
    {
        get
        {
            return (string)GetValue(TextOldProperty);
        }
        set
        {
            SetValue(TextOldProperty, value);
        }
    }

    public bool AddZeroBeforeTextIfSingleValue { get; set; }

    public SpinTextBlock()
    {
        InitializeComponent();
        AddZeroBeforeTextIfSingleValue = true;
        TextBlockOld.Visibility = Visibility.Collapsed;

    }

    void UpdateTextBlocks(string newValue)
    {
        if (AddZeroBeforeTextIfSingleValue)
        {
            AddZeroToValue(ref newValue);
        }
        TextOld = TextBlockMain.Text;
        StartAnimation();
    }

    void StartAnimation()
    {
        TextBlockOld.Visibility = Visibility.Visible;
        Storyboard sb = this.Resources["StoryboardChangeTexts"] as Storyboard;
        sb.Begin();
    }

    void AddZeroToValue(ref string value)
    {
        if (value != null && value.Length == 1)
        {
            value = "0" + value;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

UserControl xaml
<UserControl x:Class="Y.Infrastructure.SpinTextBlock.SpinTextBlock"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         x:Name="userControl"
mc:Ignorable="d"
FontSize="36"
Foreground="Black"
d:DesignHeight="60" d:DesignWidth="40">
<UserControl.Resources>
    <Storyboard x:Key="StoryboardChangeTexts">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="TextBlockOld">
            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="TextBlockMain">
            <EasingDoubleKeyFrame KeyTime="0" Value="-35"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="TextBlockOld">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.4" Value="35"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" Background="Black">
    <TextBlock HorizontalAlignment="Center" x:FieldModifier="private" Foreground="White" FontSize="36" Text="{Binding Text, ElementName=userControl}" x:Name="TextBlockMain" FontWeight="Bold" FontFamily="Segoe UI Semibold">
        <TextBlock.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform/>
            </TransformGroup>
        </TextBlock.RenderTransform>
    </TextBlock>
    <TextBlock HorizontalAlignment="Center" x:FieldModifier="private" Foreground="White" FontSize="36" Text="{Binding TextOld, ElementName=userControl}" x:Name="TextBlockOld" FontWeight="Bold" FontFamily="Segoe UI Semibold">
        <TextBlock.RenderTransform>
            <TransformGroup>
                <ScaleTransform/>
                <SkewTransform/>
                <RotateTransform/>
                <TranslateTransform/>
            </TransformGroup>
        </TextBlock.RenderTransform>
    </TextBlock>
</Grid>

      

+3


source to share


1 answer


A call UpdateTextBlocks(value)

in your property's customizer Text

won't get called because runtime will call directly SetValue(TextProperty, value);

.



+2


source







All Articles