【问题标题】:ForcingPropertyChangedCallback of a DP to fire强制 DP 的 PropertyChangedCallback 触发
【发布时间】:2013-09-02 12:40:15
【问题描述】:

我的问题可能听起来有点类似于 this question

当我的自定义 UserControl 的 DependencyProperty 发生更改时,我有一个通知栏会经历某些动画。代码实现如下:

    public string StatusBarText
    {
      get { return (string)GetValue(StatusBarTextProperty); }
      set { SetValue(StatusBarTextProperty, value); }
    }

   public static readonly DependencyProperty StatusBarTextProperty =
        DependencyProperty.Register("StatusBarText", typeof(string), typeof(WorkspaceFrame), new FrameworkPropertyMetadata(null, StatusBarTextChangedCallBack));

    private static void StatusBarTextChangedCallBack(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      if (!string.IsNullOrWhiteSpace(Convert.ToString(e.NewValue)))
      {
        var workspaceFrame = d as WorkspaceFrame;
        if (null == workspaceFrame)
          return;
        var storyboard = workspaceFrame.FindResource("notificationBarAnimation") as Storyboard;
        if (null == storyboard)
          return;
        var statusBar = workspaceFrame.Template.FindName("PART_StatusBar", workspaceFrame) as Border;
        if (null == statusBar)
          return;
        //Run the animation
        storyboard.Begin(statusBar);
      }
    }

这是动画的边框:

<Border x:Name="PART_StatusBar" Margin="5" BorderThickness="2" VerticalAlignment="Top"
                    DataContext="{Binding Path=StatusText}" Opacity="0"
                    Visibility="{Binding Path=Opacity, Mode=OneWay, RelativeSource={RelativeSource Self}, Converter={StaticResource doubleToVis}}"
                    BorderBrush="{StaticResource StatusMessageBackBrush}">

                <Border.Background>
                  <SolidColorBrush Color="{StaticResource StatusMessageBackColor}" Opacity="0.7"/>
                </Border.Background>

                <TextBlock Margin="10" FontSize="17" Foreground="{StaticResource BlackColorBrush}" Text="{Binding}">

                </TextBlock>
              </Border>

您现在可能很清楚,此 DP 绑定到一个 VM 属性,该属性在设置时会触发 PropertyChangedNotification(属于 INotifyProeprtyChanged)。 现在的问题是 StatusBarTextChangedCallBack 仅在 DP 的旧值和新值发生一些变化时才被调用。有没有办法强制它运行?如果没有,有什么办法吗? 我需要一遍又一遍地显示相同的通知。动画应该会触发。

问候,

詹姆斯

【问题讨论】:

  • 您的问题链接到另一个问题,该问题似乎提出了完全相同的问题。请说明为什么该问题及其答案不适用于您的案例。
  • 因为我不是直接通过代码设置DP。我通过绑定设置它。我将如何从 ViewModel 在我的 UserControl 中进行方法调用?
  • 为什么不使用 EventTriggers 并在其中编写故事板? EventTriggers 侦听任何 RoutedEvent,因此如果您想“强制”动画运行,只需编写自定义 routedevent 并在需要时触发它。其余的由 EventTriggers 完成。
  • 之前已经完成了。但它有一个缺点。当 View 和 ViewModel 被绑定并且 StatusBarText 为空时,它也第一次触发了故事板。如果 StatusBarText 为空或为空,我必须检查故事板不应运行。当然,我可以在 ViewModel 级别的级别上做到这一点。但是第一次呢?
  • @ninja 等一下。你说写一个自定义路由事件。我之前在 上运行过故事板。您能否再解释一下,以便我可以尝试这种方法?

标签: wpf mvvm dependency-properties change-notification


【解决方案1】:

您可以注册 CoerceValueCallBack 函数而不是 ValueChanged。像这样的:

public static readonly DependencyProperty StatusBarTextProperty =
        DependencyProperty.Register("StatusBarText", typeof(string), typeof(WorkspaceFrame), new FrameworkPropertyMetadata(null,null, StatusBarTextCoerceValueCallBack));



private static object StatusBarTextCoerceValueCallBack(DependencyObject d, object value)
{

 }

CoerceValueCallback 总是会在属性值发生变化时触发,即使值相同。

谢谢

【讨论】:

  • 我有这个想法。我不想采用这种方法,因为它不干净。但这似乎是最后的手段。
  • 在出现其他一些好的方法之前,这似乎是唯一可行的解​​决方案。它并不完美,但有效。谢谢@nit
【解决方案2】:

实现您想要的(或手动调用事件处理程序)的正常方法是创建一个方法来启动您的动画。然后从您的属性更改处理程序内部调用该动画启动方法。这样,您可以在需要时调用此方法。

【讨论】:

  • 很抱歉我没能得到它。你能详细说明吗?我正在调用代码以从 PropertyChangedHandler 内部进行动画处理。但是处理程序本身并没有被首先调用(直到 e.NewValue 发生一些变化)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多