【问题标题】:Why not to change dependency property?为什么不改变依赖属性?
【发布时间】:2018-02-27 03:17:54
【问题描述】:

这是我的自定义控制代码

public partial class FlatImageButton : ContentControl
{
    public static readonly DependencyProperty IsActiveProperty = DependencyProperty.Register("IsActive", typeof(bool?), typeof(FlatImageButton), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(IsActiveChanged)));
    public bool IsActive
    {
        get => (bool)GetValue(IsActiveProperty);
        set => SetValue(IsActiveProperty, value);
    }

    public FlatImageButton() : base()
    {
        InitializeComponent();
    }

    private static void IsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FlatImageButton button = (FlatImageButton)d;

        button.IsActive = (bool) e.NewValue;
    }
}

这是自定义控件 xaml 代码。
IsActive 属性更改 Background 属性。

<ContentControl ...>

    <Button x:Name="_Control" Focusable="False">
        <Button.Template>
            <ControlTemplate TargetType="Button">
                <Grid>
                    <Rectangle Fill="Transparent" />
                    <Border Padding="{Binding ElementName=_Root, Path=Padding}">
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                            <Image Width="24" Height="24" Source="{Binding ElementName=_Root, Path=Image}" />
                            <TextBlock Name="Text" Text="{Binding ElementName=_Root, Path=Text}" Foreground="{Binding ElementName=_Root, Path=Fill}" Margin="10,0,0,0" VerticalAlignment="Center" />
                        </StackPanel>
                        <Border.Style>
                            <Style TargetType="Border">
                                <Setter Property="Background" Value="{Binding ElementName=_Root, Path=Background}" />
                                <Style.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Background" Value="{Binding ElementName=_Root, Path=Foreground}" />
                                    </Trigger>
                                    <DataTrigger Binding="{Binding ElementName=_Root, Path=IsActive}" Value="True">
                                        <Setter Property="Background" Value="{Binding ElementName=_Root, Path=Foreground}" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Border.Style>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Button.Template>
    </Button>
</ContentControl>

尝试更改另一个控件中的“IsActive”时出现问题。

<common:FlatImageButton Tag="{x:Static enum:Coin.ETHEREUM}" x:Name="_CEthereum" Cursor="Hand" Padding="10, 10" Text="{Binding ViewModel.Coin,ElementName=_Root}" Background="#EEE" Foreground="#DDD" Fill="#333" Image="pack://application:,,,/Resources/ethereum.png">
  <common:FlatImageButton.Style>
    <Style TargetType="common:FlatImageButton">
      <Setter Property="IsActive" Value="False" />
      <Style.Triggers>
        <DataTrigger Binding="{Binding ViewModel.Coin, ElementName=_Root}" Value="ETHEREUM">
          <Setter Property="IsActive" Value="True" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </common:FlatImageButton.Style>
</common:FlatImageButton>

为什么不改变财产?

详情:

  • ViewModel.Coin 值始终为 ETHEREUM。

【问题讨论】:

  • 文本绑定,即Text="{Binding ViewModel.Coin,ElementName=_Root}" 是否有效?尝试使用实际的枚举值而不是字符串作为 DataTrigger 的值,就像对 Tag 属性所做的那样。
  • Text="{Binding ViewModel.Coin,ElementName=_Root}" 正在工作。
  • 好的,你试过Value="{x:Static enum:Coin.ETHEREUM}"而不是Value="ETHEREUM"吗?
  • 是的。它不工作。 :(
  • 目前还不清楚“不工作”的真正含义。您还没有展示 IsActive 属性更改时应该发生的情况。你怎么知道它没有改变?

标签: wpf


【解决方案1】:

属性改变回调其实是不需要的,你可以去掉它,把属性元数据留下new FrameworkPropertyMetadata(false)。

属性改变回调是值改变后需要执行的逻辑,不建议在回调函数中改变属性值。

【讨论】:

  • 我已经删除了new FrameworkPropertyMetadata。但是,它不起作用。
  • 虽然这当然是正确的,但它并不能回答问题。它应该是一个评论。
【解决方案2】:

尝试将您的 IsActive 更改为 common::FlatImageButton.IsActive

你也可以看到Trigger for custom dependency properties in Style

【讨论】:

  • 不是这样的。我需要在另一个控件中使用触发器。
  • 这里有两个问题: 1. 您如何验证“IsActive”不起作用? (例如通过检查背景是否改变) 2. ElementName "_Root" 代表什么?小提示:调试绑定错误时可以参考“输出”窗口。
猜你喜欢
  • 2010-12-15
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 2012-01-07
  • 2011-02-04
相关资源
最近更新 更多