首页 > 解决方案 > Usercontrol - 从 ViewModel 通知属性更改

问题描述

我正在尝试实现自定义边框,它绑定到 ViewModel 中的 bool 属性,并且每当这个属性发生变化时,我想用边框做一些动画。

ViewModel 属性有 OnPropertyChanged 接口,它看起来像这样:

public bool Enable_control
{
   get { return _enable_ctl; }
   set { _enable_ctl = value; OnPropertyChanged(); }
}
private bool _enable_ctl;

这就是我在 xaml 中绑定自定义边框的方式:

<cust_border:Border_slide ShowSlide={Binding Enable_control}"/>

这是我的自定义边界控制代码:

public class Border_slide : Border
{
    public Border_slide()
    {
    }
 
     public bool ShowSlide
     {
        get { return (bool)GetValue(ShowSlideProperty); }
        set { SetValue(ShowSlideProperty, value);}
     }
    
      public static readonly DependencyProperty ShowSlideProperty =
      DependencyProperty.Register("ShowSlide", typeof(bool), typeof(Border_slide), new 
      FrameworkPropertyMetadata(true, new PropertyChangedCallback(ShowSlideChanged)));
           
      private static void ShowSlideChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
           //I would like to do animation of control when property of ViewModel changes - presumably here,
           //but PropertyChangedCallback gets triggered only once - not on every Enable_control change!
      }
}

所以,问题是:如何从 Viewmodel 属性更改中正确更新 UserControl 的依赖属性,以便接下来对 UserControl 做一些事情?

标签: c#wpfbindingdependency-propertiesinotifypropertychanged

解决方案


曾经有一段时间我做了和你类似的事情。

就我而言,我希望它会有所帮助,因为我以这种方式解决了它。但它可能与您的想法不同,所以如果我错过了什么,请告诉我!

我已经将我的示例源代码上传到了GitHub。

这里是示例源代码。https://github.com/ncoresoftsource/stackoverflowsample/tree/main/src/answers/dependency-border-animation

视图模型

public class MainViewModel : ObservableObject
{
    private bool _enable_ctl;
    public bool Enable_control
    {
        get { return _enable_ctl; }
        set { _enable_ctl = value; OnPropertyChanged(); }
    }
}

主窗口

我使用标签而不是边框​​。因为Border不能使用ControlTemplate,所以可以限制使用和展开动画。

<CheckBox Content="Switch" IsChecked="{Binding Enable_control}"/>
<Label Style="{StaticResource SLIDER}"/>

应用程序.xaml

<Style TargetType="Label" x:Key="SLIDER">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="BorderBrush" Value="#AAAAAA"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="Width" Value="100"/>
    <Setter Property="Height" Value="100"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Label">
                <Border x:Name="border" Background="{TemplateBinding Background}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        Opacity="0">
                    <ContentPresenter/>
                </Border>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding Enable_control}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation From="0" To="1" Duration="00:00:0.5" 
                                                     Storyboard.TargetName="border" 
                                                     Storyboard.TargetProperty="Opacity"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation From="1" To="0" Duration="00:00:0.5" 
                                                     Storyboard.TargetName="border" 
                                                     Storyboard.TargetProperty="Opacity"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

推荐阅读