0

My question might sound a bit similar to this question

I have a Notification bar that undergoes certain Animations when a DependencyProperty of my custom UserControl changes. Here goes the code implmentation:

    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);
      }
    }

and here is the Border that is getting animated:

<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>

As it might be clear to you by now, that this DP is bound to a VM property which fires the PropertyChangedNotification (of INotifyProeprtyChanged) when set. Now the problem is the StatusBarTextChangedCallBack is called only if there is some change in the Old and New value of the DP. Is there a way to force it to run? If not, is there some way around? I need to show the same notification over and over. And the animation should fire.

regards,

James

Community
  • 1
  • 1
James
  • 1,213
  • 2
  • 15
  • 26
  • Your question links to another question that seems to ask the exact same thing. Please specify why that question and its answer is not applicable in your case. – Daniel Hilgarth Sep 02 '13 at 12:45
  • Because I am not setting the DP directly through code. I am setting it through binding. How am I going to make a method call in my UserControl from the ViewModel? – James Sep 02 '13 at 12:50
  • Why dont you use EventTriggers and you write your storyboard inside it? EventTriggers listen to any RoutedEvent so if you want to "force" the animation to run just write your custom routedevent and fire it whenever you want. The EventTriggers does the rest. – ninja hedgehog Sep 02 '13 at 12:53
  • Previously that was done. But it had a drawback. It fired the storyboard for the first time too when the View and ViewModel were bound and the StatusBarText was null. I have to put a check that the storyborad should not run if the StatusBarText is null or empty. Ofcourse I can do it at the ViewModel level level itelf. But what about the first time? – James Sep 02 '13 at 13:58
  • @ninja wait a sec. You said writing a cutom routed event. I had previously run the storyboard on . Would you be kind enough to elucidate a little more so that I may try that approach? – James Sep 02 '13 at 14:03
  • I dont get your question. Tell us more from where exactly do you wish to trigger your animation? Once you change StatusBarText then you wish something to happen? Then listen to TextChanged event in EventTrigger. – ninja hedgehog Sep 02 '13 at 14:51

2 Answers2

1

You can register a CoerceValueCallBack function instead of ValueChanged. Something like this:

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 will always be triggered when the value of a property changes even if the value is same.

Thanks

Nitin
  • 18,344
  • 2
  • 36
  • 53
  • I had this thing in mind.I didn't want to go by this approach as it is not clean. But it seems to be the last resort. – James Sep 02 '13 at 12:55
  • Until some other nice approach comes up, this seems to be the only viable solution. It is not perfect but works. Thanks @nit – James Sep 02 '13 at 12:57
1

The normal way to achieve what you want (or calling an event handler manually) is to create a method to start your animations. Then call that animation starting method from inside your property changed handler. This way, you can simply call this method whenever you need to.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • I am sorry I could not get it. Can you elaborate? I am calling the code to animate from inside the PropertyChangedHandler. But the handler itself is not getting called at the first place (until there is some change in the e.NewValue). – James Sep 02 '13 at 13:00