绑定不会正确更新用户控件属性 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>
不会
调用属性Text
的 setter 中的调用UpdateTextBlocks(value)
,因为运行时将直接调用SetValue(TextProperty, value);
。