【问题标题】:Binding does not update usercontrol property correctly MVVM绑定没有正确更新用户控件属性 MVVM
【发布时间】:2013-01-24 08:58:00
【问题描述】:

编辑:删除旧代码

我将它放在我的 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");
        }
    }

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

谁有办法解决这个问题?

编辑工作解决方案

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

    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>

【问题讨论】:

  • 您真的在使用 Silverlight 4 吗?因为在 Silverlight 5 中添加了 UpdateSourceTrigger.PropertyChanged
  • 这次通话Dispatcher.CurrentDispatcher.BeginInvoke( new Action&lt;String&gt;(RaisePropertyChanged), DispatcherPriority.DataBind, "WelcomeTitle");是什么情况?
  • 我的错是 Silverlight 5。我必须添加它才能更新文本块,RaisePropertyChanged 没有更新视图中的值。在这里找到它:stackoverflow.com/questions/3055826/…

标签: c# wpf xaml binding silverlight-5.0


【解决方案1】:

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

【讨论】:

  • 没有用。用户控件中的 Text-property 仍然从未被调用,然后从 VM 更新绑定。
  • 谢谢您,您为我指明了正确的方向!有关工作解决方案,请参阅我的原始帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 1970-01-01
  • 2020-01-07
  • 1970-01-01
  • 2018-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多