【问题标题】:How to bind Fill property to a custom property into a controltemplate如何将 Fill 属性绑定到自定义属性到控件模板中
【发布时间】:2012-03-19 16:17:54
【问题描述】:

我有一个按钮控件,它的模板在外部资源 Theme.xaml 中被样式化。控制模板定义下方:

    <ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type Button}">
     <Grid x:Name="Grid">
       <Border x:Name="Background" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="2,2,2,2" CornerRadius="2,2,2,2">
       <Border x:Name="Hover" Background="{StaticResource HoverBrush}" CornerRadius="1,1,1,1" Height="Auto" Width="Auto" Opacity="0"/>
       </Border>
       <StackPanel Orientation="Horizontal" Margin="2,2,2,2">
          <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True" />
       </StackPanel>

...

现在我添加了一个椭圆项目,该项目必须填充红色或绿色(作为信号量),具体取决于我的用户控件中定义的自定义属性:

<UserControl.Resources>
    <ResourceDictionary Source="Themes/theme.xaml"/>
</UserControl.Resources>

<Grid>
    <Button Click="Button_Click"></Button>

    <Ellipse x:Name="ellipse1" Width="20" Height="20"  Margin="5,40,45,5"></Ellipse>

</Grid>

在后面的代码中我有:

private SolidColorBrush ButtonValue_;
public SolidColorBrush ButtonValue {
    get { return ButtonValue_; }
    set {
        ButtonValue_ = value;
    }
}

我正在尝试将这个椭圆项目放入 CONTROLTEMPLATE,但我有一些关于如何使用 ButtonValue 自定义属性绑定椭圆的 Fill 属性的问题进入控制模板。

有什么提示吗?? 提前致谢

【问题讨论】:

    标签: wpf wpf-controls


    【解决方案1】:

    你可以去几个方向:

    1. 实现一个自定义控件,这是您自己的从现有控件(在您的情况下为按钮)派生的类。添加依赖属性(例如 ButtonValue)。注意 - 依赖属性不是标准的 .NET 属性 - 它们还有更多。查看以下示例:http://msdn.microsoft.com/en-us/library/cc295235(v=expression.30).aspx(自定义按钮)或此处:http://wpftutorial.net/HowToCreateACustomControl.html(更简单的示例,但没有属性。

    2. 拥有控件的数据上下文。通常,数据上下文是一个单独的类(也称为“视图模型”),但如果您不遵循 mvvm 范例,则数据上下文是自己的也没关系。无论您使用什么数据上下文,它都必须从 INotifyPropertyChanged 派生,并且必须归档 PropertyChanged 事件。

    3. (推荐!)为 CheckBox 创建一个控制模板。仔细想想,逻辑上您的控件实际上是一个具有二进制状态的按钮。在您的情况下为红色/绿色,选中/未选中复选框。所以从逻辑上讲,您正在寻找一个复选框,但您只是想以不同的方式呈现它。

    因此,在您的控件模板中,绘制椭圆,并为 IsChecked 属性添加触发器:

    <ControlTemplate x:Key="ButtonTemplate" TargetType="{x:Type CheckBox}">
        <Grid>
            ... everything else in the control ...
            <Ellipse x:Name="ellipse1" Width="20" Height="20"  Margin="5,40,45,5" />
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="IsChecked" Value="True">
                <Setter TargetName="ellipse1" Property="Fill" Value="Red" />
            </Trigger>
            <Trigger Property="IsChecked" Value="False">
                <Setter TargetName="ellipse1" Property="Fill" Value="Green" />
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    

    这是一个很好的例子,说明了 WPF 的 行为表示 之间的差异。 虽然您的控件可能看起来像一个按钮,但它的行为就像一个 CheckBox,因为它有两种状态。

    编辑:使用 ToggleButton - 这是 CheckBox(和 RadioButton)的基类,它具有您需要的功能,包括 IsChecked 属性。

    【讨论】:

      【解决方案2】:

      你有几个选择:

      1.最简单的方法是重新使用未使用的画笔或颜色(带有转换器)按钮现有属性:

       <Window.Resources>
            <ControlTemplate x:Key="repurposedProperty" TargetType="Button">
              <Border Background="{TemplateBinding BorderBrush}">
                <ContentPresenter/>
              </Border>
             </ControlTemplate>
          </Window.Resources>
      

      ...

      <Button Template="{StaticResource repurposedProperty}">Button</Button>
      

      2.其他选项是定义一个附加属性并在 ControlTemplate 中使用它。在您应用模板的任何 Button 上,您必须设置附加属性:

      public static readonly DependencyProperty AttachedBackgroundProperty =
                  DependencyProperty.RegisterAttached("AttachedBackground", typeof (Brush), typeof (MainWindow), 
                  new PropertyMetadata(default(Brush)));
      
              public static void SetAttachedBackground(UIElement element, Brush value)
              {
                  element.SetValue(AttachedBackgroundProperty, value);
              }
      
              public static Brush GetAttachedBackground(UIElement element)
              {
                  return (Brush) element.GetValue(AttachedBackgroundProperty);
              }
      

      ...

      Window.Resources>
              <ControlTemplate x:Key="attachedProperty" TargetType="Button">
                  <Border Background="{TemplateBinding WpfApplication1:MainWindow.AttachedBackground}">
                      <ContentPresenter/>
                  </Border>
              </ControlTemplate>
          </Window.Resources>
      

      ...

      <Button Template="{StaticResource attachedProperty}">
                  <WpfApplication1:MainWindow.AttachedBackground>
                      <SolidColorBrush Color="Pink"></SolidColorBrush>
                  </WpfApplication1:MainWindow.AttachedBackground>
        Button</Button>
      

      PS:您可以使用绑定来设置附加属性的值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-05-11
        • 2012-08-29
        • 1970-01-01
        • 2011-08-29
        • 2011-06-22
        • 2013-12-25
        相关资源
        最近更新 更多