绑定不会正确更新用户控件属性 MVVM

本文关键字:用户 控件 属性 MVVM 更新 绑定 | 更新日期: 2023-09-27 17:56:01

编辑:删除旧代码

我把它放在我的MainWindow.xaml上

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

并将其绑定到 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");
        }
    }

一切正常,除了我的用户控件中的属性文本在更新视图模型中的值时不会更新。相反,来自 ViewModel 的更新直接放置在 TextBlock(在用户控件中)上,并且根本不调用情节提要和我的用户控件上的所有属性。

有人有解决方案吗?

编辑工作解决方案

用户控件代码隐藏。必须侦听属性更改才能启动我的故事板并更新属性。

    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>

绑定不会正确更新用户控件属性 MVVM

不会

调用属性Text的 setter 中的调用UpdateTextBlocks(value),因为运行时将直接调用SetValue(TextProperty, value);