在XAML中添加自定义依赖属性来控制模板 [英] Adding a custom dependency property to a Control Template in XAML

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

问题描述

我设法进一步得到我只读了一点休息后复选框,现在我想在一个合理的优雅形态的功能。问题是我用一个黑客位,使其工作,尽管这不是这将是很好做的更好一场灾难。

要回顾一下:我想经常看它的复选框被点击时,而不是点击事件触发后台工作,后来就导致一个变量进行更新,这并不自检。这个变量绑定到checkbox.ischecked并且它然后用新的值更新。

我想用基于这样的思想在这里控件模板:

<一个href=\"http://stackoverflow.com/questions/921921/a-read-only-checkbox-in-c-wpf\">http://stackoverflow.com/questions/921921/a-read-only-checkbox-in-c-wpf

我已经修改这一点,并剥离出来的东西,我想我并不需要(也许是不明智),并结束了:

 &LT; ResourceDictionary中的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
xmlns:Microsoft_Windows_Themes=\"clr-namespace:Microsoft.Windows.Themes;assembly=$p$psentationFramework.Aero\">
&所述;! - - &GT;
&LT;风格X:键=ReadOnlyCheckBoxStyle的TargetType ={X:类型的CheckBox}&GT;
        &LT; setter属性=Control.Template&GT;
        &LT; Setter.Value&GT;
            &LT;的ControlTemplate的TargetType ={X:类型的CheckBox}&GT;
                &LT; BulletDecorator SnapsToDevicePixels =真正的背景=透明&GT;
                    &LT; BulletDecorator.Bullet&GT;
                        &LT; Microsoft_Windows_Themes:BulletChrome背景={TemplateBinding背景}
                                                               BorderBrush ={TemplateBinding BorderBrush}
                                                               RenderMouseOver ={TemplateBinding IsMouseOver}
                                                               器isChecked ={TemplateBinding标签}&GT;
                        &LT; / Microsoft_Windows_Themes:BulletChrome&GT;
                    &LT; /BulletDecorator.Bullet>
                    &lt;内容presenter SnapsToDevicePixels ={TemplateBinding SnapsToDevicePixels}
                                      的Horizo​​ntalAlignment ={TemplateBinding Horizo​​ntalContentAlignment}
                                      保证金={TemplateBinding填充}
                                      VerticalAlignment ={TemplateBinding VerticalContentAlignment}
                                      RecognizesAccessKey =真/&GT;
                &LT; / BulletDecorator&GT;
                &LT; ControlTemplate.Triggers&GT;
                    &LT;触发属性=IsEnabledVALUE =false的&GT;
                        &LT; setter属性=前景VALUE ={StaticResource的{X:静态SystemColors.GrayTextBrushKey}}/&GT;
                    &LT; /触发&GT;
                &LT; /ControlTemplate.Triggers>
            &LT; /控件模板&GT;
        &LT; /Setter.Value>
    &LT; /二传手&GT;
&LT; /样式和GT;

此复选框工作如上所述,我把它叫做是这样的:

 &LT;复选框X:NAME =uiComboBoxCONTENT =不设置后盾属性,但响应为
                  风格={StaticResource的ReadOnlyCheckBoxStyle}标签={结合MyBoolean}点击=uiComboBox_Click/&GT;

我做的黑客是使用标签的DependencyProperty进行数据绑定到控件模板。这绕过任何机制通常是造成复选框自检。要恢复到正常的演技复选框只更改绑定标签的绑定和器isChecked的BulletDecorator内设置TemplateBinding来的器isChecked而不是标签。

所以,我想我的问题是:


  1. 让我得到了坚持错误的结束?有没有在那里我可以覆盖任何机制导致框自检的地方吗?也许在控件模板触发器
    解决方案

    我设法理清这个问题,我ReadOnlyCheckBox的想法,最终我创建了一个基于各地按钮自定义的控件,然后加一个风格使它看起来像一个复选框。我说我自己的财产器isChecked不获取设置用户点击时,但被绑定到数据如此显示的检查只出现在数据的变化。

    C#:

     公共类ReadOnlyCheckBoxControl:System.Windows.Controls.Button
    {
        公共静态的DependencyProperty IsCheckedProperty;    公共ReadOnlyCheckBoxControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof运算(ReadOnlyCheckBoxControl),新FrameworkPropertyMetadata(typeof运算(ReadOnlyCheckBoxControl)));
        }    公共BOOL器isChecked
        {
            {返回(布尔)的GetValue(IsCheckedProperty); }
            集合{的SetValue(IsCheckedProperty,值); }
        }    静态ReadOnlyCheckBoxControl()
        {
            IsCheckedProperty = DependencyProperty.Register(器isChecked的typeof(布尔)的typeof(ReadOnlyCheckBoxControl));
        }
    }

    XAML:

     &LT; ResourceDictionary中的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
    的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
    的xmlns:Y =CLR的命名空间:ReadOnlyCheckBoxControlNS;装配=
    xmlns:Microsoft_Windows_Themes=\"clr-namespace:Microsoft.Windows.Themes;assembly=$p$psentationFramework.Aero\">&LT;的SolidColorBrush X:键=CheckBoxFillNormal颜色=#F4F4F4/&GT;
    &LT;的SolidColorBrush X:键=CheckBoxStroke颜色=#8E8F8F/&GT;&LT;风格X:键=EmptyCheckBoxFocusVisual&GT;
        &LT; setter属性=Control.Template&GT;
            &LT; Setter.Value&GT;
                &LT;&控件模板GT;
                    &LT;矩形SnapsToDevicePixels =真
                               余量=1
                               行程=黑
                               StrokeDashArray =1 2
                               StrokeThickness =1/&GT;
                &LT; /控件模板&GT;
            &LT; /Setter.Value>
        &LT; /二传手&GT;
    &LT; /样式和GT;&LT;风格X:键=CheckRadioFocusVisual&GT;
        &LT; setter属性=Control.Template&GT;
            &LT; Setter.Value&GT;
                &LT;&控件模板GT;
                    &LT;矩形SnapsToDevicePixels =真
                               保证金=14,0,0,0
                               行程=黑
                               StrokeDashArray =1 2
                               StrokeThickness =1/&GT;
                &LT; /控件模板&GT;
            &LT; /Setter.Value>
        &LT; /二传手&GT;
    &LT; /样式和GT;&LT;风格的TargetType ={X:输入y:ReadOnlyCheckBoxControl}&GT;
        &LT; setter属性=模板&GT;
            &LT; Setter.Value&GT;
                &LT;的ControlTemplate的TargetType ={X:输入y:ReadOnlyCheckBoxControl}&GT;
                    &LT; BulletDecorator SnapsToDevicePixels =真正的背景=透明&GT;
                        &LT; BulletDecorator.Bullet&GT;
                            &LT; Microsoft_Windows_Themes:BulletChrome背景={S​​taticResource的CheckBoxFillNormal}
                                                                   BorderBrush ={StaticResource的CheckBoxStroke}
                                                                   RenderMouseOver ={TemplateBinding IsMouseOver}
                                                                   器isChecked ={TemplateBinding}器isChecked&GT;
                            &LT; / Microsoft_Windows_Themes:BulletChrome&GT;
                        &LT; /BulletDecorator.Bullet>
                        &lt;内容presenter SnapsToDevicePixels =真
                                          的Horizo​​ntalAlignment =左
                                          保证金=4,0,0,0
                                          VerticalAlignment =中心
                                          RecognizesAccessKey =真/&GT;
                    &LT; / BulletDecorator&GT;
                    &LT; ControlTemplate.Triggers&GT;
                        &LT;触发属性=HasContentVALUE =真正的&GT;
                            &LT; setter属性=FocusVisualStyleVALUE ={StaticResource的CheckRadioFocusVisual}/&GT;
                            &LT; setter属性=填充VALUE =4,0,0,0/&GT;
                        &LT; /触发&GT;
                        &LT;触发属性=IsEnabledVALUE =false的&GT;
                            &LT; setter属性=前景VALUE ={StaticResource的{X:静态SystemColors.GrayTextBrushKey}}/&GT;
                        &LT; /触发&GT;
                    &LT; /ControlTemplate.Triggers>
                &LT; /控件模板&GT;
            &LT; /Setter.Value>
        &LT; /二传手&GT;
    &LT; /样式和GT;

    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.

    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:

    http://stackoverflow.com/questions/921921/a-read-only-checkbox-in-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>
    

    This checkbox works as described above and I call it like this:

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

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

      解决方案

      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天全站免登陆