基于 DependencyProperty 控制样式

发布于 2024-12-11 03:50:46 字数 2754 浏览 0 评论 0原文

因此,我正在使用 MV-VM 设计模式制作一个 WPF 应用程序,但在让我的绑定正常工作时遇到了一些问题。

我有一个自定义 ToggleButton,我希望它的工作方式是这样的:

  1. 当控件的 IsChecked 属性设置为 true 时,它​​应该查询第二个布尔值(包含在 ViewModel 中)是否也为 true。
  2. 如果是,则将背景颜色设置为一种颜色,如果不是,则将其设置为其他颜色。
  3. 如果 IsChecked 为 false,则使用标准颜色。

在xaml中,我有这样的样式:

<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource CustomisableToggleButton}" x:Key="ValidatedTButton">
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsChecked}" Value="True" />
                <Condition Binding="{Binding IsValid}" Value="True" />
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.Setters>
                <Setter Property="Background" Value="Turquoise" />
            </MultiDataTrigger.Setters>
        </MultiDataTrigger>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsChecked}" Value="True" />
                <Condition Binding="{Binding IsValid}" Value="False" />
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.Setters>
                <Setter Property="Background" Value="LightCoral" />
            </MultiDataTrigger.Setters>
        </MultiDataTrigger>
        <DataTrigger Binding="{Binding IsChecked}" Value="False">
            <Setter Property="Background" Value="AliceBlue" />
        </DataTrigger>
    </Style.Triggers>
</Style>

(CustomisableToggleButton是一个适用于ToggleButtons的包罗万象的样式-据我所知,这应该覆盖其中固有的触发器-如果我错了,请纠正我)

在控制类中:

public class ValidatedToggleButton : ToggleButton
{
    public ValidatedToggleButton()
        : base() { }

    public static readonly DependencyProperty IsValidProperty = DependencyProperty.Register(
        "IsValid", typeof(bool), typeof(ValidatedToggleButton));

    public bool IsValid
    {
        get { return (bool)GetValue(IsValidProperty); }
        set { SetValue(IsValidProperty, value); }
    }
}

以及实际的实现该控件的特点是:

<Window
<!--standard window properties-->
    xmlns:cc="clr-namespace:MVVM.CustomControls"> // namespace where 'ValidatedToggleButton' resides

<!--other XAML code-->

    <cc:ValidatedToggleButton 
        IsValid="{Binding Boolean1}" 
        Content="ToggleButton1" 
        IsChecked="{Binding ToggleButton1Checked}" 
        Grid.Row="6" Style="{StaticResource ValidatedTButton}" />

</Window>

现在的问题是,除了启动时(使用断点验证)之外,它从不检查“Boolean1”值。如何让它在每次按下控件时检查该值?

So, I'm making a WPF Application using the M-V-VM design pattern and having some trouble getting my Bindings to work properly.

I have a custom ToggleButton, and the way I want it to work is this:

  1. When the IsChecked property of the control is set to true, then it should query a second boolean (contained within the ViewModel) is also true.
  2. If it is, set the background colour to one colour, if not then set it to a different colour.
  3. If IsChecked is false, use the standard colour.

In the xaml, I have this style:

<Style TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource CustomisableToggleButton}" x:Key="ValidatedTButton">
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsChecked}" Value="True" />
                <Condition Binding="{Binding IsValid}" Value="True" />
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.Setters>
                <Setter Property="Background" Value="Turquoise" />
            </MultiDataTrigger.Setters>
        </MultiDataTrigger>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding IsChecked}" Value="True" />
                <Condition Binding="{Binding IsValid}" Value="False" />
            </MultiDataTrigger.Conditions>
            <MultiDataTrigger.Setters>
                <Setter Property="Background" Value="LightCoral" />
            </MultiDataTrigger.Setters>
        </MultiDataTrigger>
        <DataTrigger Binding="{Binding IsChecked}" Value="False">
            <Setter Property="Background" Value="AliceBlue" />
        </DataTrigger>
    </Style.Triggers>
</Style>

(CustomisableToggleButton is a catch all style that applies to ToggleButtons - AFAIK this should override the triggers that are inherent in that - correct me if I'm wrong)

In the Control Class:

public class ValidatedToggleButton : ToggleButton
{
    public ValidatedToggleButton()
        : base() { }

    public static readonly DependencyProperty IsValidProperty = DependencyProperty.Register(
        "IsValid", typeof(bool), typeof(ValidatedToggleButton));

    public bool IsValid
    {
        get { return (bool)GetValue(IsValidProperty); }
        set { SetValue(IsValidProperty, value); }
    }
}

And the actual implementation of the control is:

<Window
<!--standard window properties-->
    xmlns:cc="clr-namespace:MVVM.CustomControls"> // namespace where 'ValidatedToggleButton' resides

<!--other XAML code-->

    <cc:ValidatedToggleButton 
        IsValid="{Binding Boolean1}" 
        Content="ToggleButton1" 
        IsChecked="{Binding ToggleButton1Checked}" 
        Grid.Row="6" Style="{StaticResource ValidatedTButton}" />

</Window>

Now, the problem is, it never checks the 'Boolean1' value apart from once at startup (verified using breakpoints). How can I make it check that value every time the control is pressed?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

忆梦 2024-12-18 03:50:46
<Condition Binding="{Binding IsChecked}" Value="True" />

这是在您的视图模型(您的数据上下文)上查找名为 IsChecked 的属性。你确定你不想要这个吗:

<Condition Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="True" />
<Condition Binding="{Binding IsChecked}" Value="True" />

This is looking for a property called IsChecked on your view model (your data context). Are you sure you don't want this:

<Condition Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="True" />
零度℉ 2024-12-18 03:50:46

除了修复 XAML 绑定的 Kent 的答案 ,验证当 Boolean1 更改时是否引发 PropertyChanged 事件。

您可以通过在 get 方法中插入断点来完成此操作。

In addition to Kent's Answer of fixing your XAML bindings, verify that the PropertyChanged event is getting raised when Boolean1 is changing.

You can do this by inserting a breakpoint in the get method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文