在XAML中将定制依赖关系属性添加到控制模板 [英] Adding a custom dependency property to a Control Template in XAML

查看:375
本文介绍了在XAML中将定制依赖关系属性添加到控制模板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经设法进一步与我的只读复选框后一点休息,现在有一个合理优雅的形式我想要的功能。问题是我使用了一点黑客来使它工作,虽然这不是一个灾难,这将是很好,做得更好。

I have managed to get further with my read only check box after a bit of a break and now have the functionality I want in a reasonably elegant form. The problem is I have used a bit of a hack to make it work, although this is not a disaster it would be nice to do it better.

重述:I想要一个常规的复选框,它不会自行检查什么时候点击,而是点击事件触发一个后台工作者,以后导致一个变量被更新。此变量绑定到checkbox.ischecked,然后用新值更新。

To recap: I want a regular looking checkbox that does not self check when it is clicked, instead the click event triggers a background worker that later on causes a variable to be updated. This variable is bound to checkbox.ischecked and it is then updated with the new value.

我想根据这里的想法使用控制模板:

I would like to use a control template based on the idea here:

一个只读的复选框C#WPF

我对此进行了修改,并删除了我认为我不需要(可能不明智)的结果:

I have modified this and stripped out stuff I thought I didn't need (perhaps unwisely) and ended up with:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">
<!-- -->
<Style x:Key="ReadOnlyCheckBoxStyle" TargetType="{x:Type CheckBox}" >
        <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <BulletDecorator SnapsToDevicePixels="true" Background="Transparent">
                    <BulletDecorator.Bullet>
                        <Microsoft_Windows_Themes:BulletChrome Background="{TemplateBinding Background}"
                                                               BorderBrush="{TemplateBinding BorderBrush}"
                                                               RenderMouseOver="{TemplateBinding IsMouseOver}"
                                                               IsChecked="{TemplateBinding Tag}">
                        </Microsoft_Windows_Themes:BulletChrome>
                    </BulletDecorator.Bullet>
                    <ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                      Margin="{TemplateBinding Padding}"
                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                      RecognizesAccessKey="True" />
                </BulletDecorator>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.GrayTextBrushKey}}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我这样调用:

<CheckBox x:Name="uiComboBox" Content="Does not set the backing property, but responds to it." 
                  Style="{StaticResource ReadOnlyCheckBoxStyle}" Tag="{Binding MyBoolean}" Click="uiComboBox_Click"/>

我做的黑客是使用'Tag'DependencyProperty来将数据绑定到控制模板。这绕过了通常导致复选框自检的任何机制。要恢复到正常的动作复选框,只需将绑定更改绑定到绑定到IsChecked和BulletDecorator设置TemplateBinding到IsChecked而不是标签。

The hack I made was to use the 'Tag' DependencyProperty to carry the data binding into the control template. This bypasses whatever mechanism is normally causing the checkbox to self check. To revert to a normal acting checkbox just change binding to Tag to a binding to IsChecked and inside the BulletDecorator set the TemplateBinding to IsChecked instead of Tag.

所以我想我的问题分别是:

So I guess my questions are:


  1. 我有错误的一端吗?是否有一个地方,我可以覆盖任何机制导致框自我检查?也许在ControlTemplate触发器?

  2. 这是一个好主意,去除去任何备用的XAML,我认为是从默认的CheckBox引入,或者我应该尝试并保持完全替换所有样式?

  3. 如果我所做的不是太疯狂,我可以在XAML中添加一个依赖属性,以便我不必使用Tag属性?

  4. 我也发现,也许我真正想要的是一个按钮控件,看起来像一个复选框,也许一个不可见的按钮与通常的动画复选框顶部,我绑定数据到的图形。

  1. Have I got the wrong end of the stick? Is there a place where I can override whatever mechanism causes the box to self check? Perhaps in ControlTemplate Triggers?
  2. Is it a good idea to go around eliminating any spare XAML that I think is just being brought in from the default CheckBox or should I try and keep a complete replacement for all styles?
  3. If what I am doing is not too crazy, can I add a dependency property in XAML so that I don't have to use the Tag property?
  4. It also occurs to me that perhaps what I really want is a button control that looks like a checkbox, maybe an invisible button with the usual animated checkbox on top which I bind data to the graphic of. Any thoughts on that plan would also be very welcome.

非常感谢

$

推荐答案

我设法解决了这个问题和我的ReadOnlyCheckBox的想法,最后我创建了一个自定义控件按钮,然后应用一个样式,使它看起来像一个复选框。我添加了自己的IsChecked属性,当用户单击但绑定到数据时,不会设置,因此显示的检查仅在数据更改时出现。

I managed to sort out this problem and my ReadOnlyCheckBox idea, in the end I created a custom control based around Button and then applied a style to make it look like a CheckBox. I added my own IsChecked property that does not get set when the user clicks but is bound to the data so the displayed check only appears when the data changes.

C#:

    public class ReadOnlyCheckBoxControl : System.Windows.Controls.Button
{
    public static DependencyProperty IsCheckedProperty;

    public ReadOnlyCheckBoxControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(ReadOnlyCheckBoxControl), new FrameworkPropertyMetadata(typeof(ReadOnlyCheckBoxControl)));
    }

    public bool IsChecked
    {
        get { return (bool)GetValue(IsCheckedProperty); }
        set { SetValue(IsCheckedProperty, value); }
    }

    static ReadOnlyCheckBoxControl()
    {
        IsCheckedProperty = DependencyProperty.Register("IsChecked", typeof(bool), typeof(ReadOnlyCheckBoxControl));
    }
}

XAML:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:y="clr-namespace:ReadOnlyCheckBoxControlNS;assembly="
xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero">

<SolidColorBrush x:Key="CheckBoxFillNormal" Color="#F4F4F4" />
<SolidColorBrush x:Key="CheckBoxStroke" Color="#8E8F8F" />

<Style x:Key="EmptyCheckBoxFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle SnapsToDevicePixels="true"
                           Margin="1"
                           Stroke="Black"
                           StrokeDashArray="1 2"
                           StrokeThickness="1" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="CheckRadioFocusVisual">
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate>
                <Rectangle SnapsToDevicePixels="true"
                           Margin="14,0,0,0"
                           Stroke="Black"
                           StrokeDashArray="1 2"
                           StrokeThickness="1" />
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style TargetType="{x:Type y:ReadOnlyCheckBoxControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type y:ReadOnlyCheckBoxControl}">
                <BulletDecorator SnapsToDevicePixels="true" Background="Transparent">
                    <BulletDecorator.Bullet>
                        <Microsoft_Windows_Themes:BulletChrome Background="{StaticResource CheckBoxFillNormal}"
                                                               BorderBrush="{StaticResource CheckBoxStroke}"
                                                               RenderMouseOver="{TemplateBinding IsMouseOver}"
                                                               IsChecked="{TemplateBinding IsChecked}">
                        </Microsoft_Windows_Themes:BulletChrome>
                    </BulletDecorator.Bullet>
                    <ContentPresenter SnapsToDevicePixels="True"
                                      HorizontalAlignment="Left"
                                      Margin="4,0,0,0"
                                      VerticalAlignment="Center"
                                      RecognizesAccessKey="True" />
                </BulletDecorator>
                <ControlTemplate.Triggers>
                    <Trigger Property="HasContent" Value="true">
                        <Setter Property="FocusVisualStyle" Value="{StaticResource CheckRadioFocusVisual}" />
                        <Setter Property="Padding" Value="4,0,0,0" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Foreground" Value="{StaticResource {x:Static SystemColors.GrayTextBrushKey}}" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这篇关于在XAML中将定制依赖关系属性添加到控制模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆