【问题标题】:Defining a control template for a rectangle in XAML在 XAML 中为矩形定义控件模板
【发布时间】:2012-11-20 16:27:28
【问题描述】:

在我当前的项目中,我有这个 XAML 文件,我在其中定义了必须应用于不同类型的自定义小部件的视觉样式。

例如,'DirectLineButton'(继承自 WPF 的 Button 的自定义类)的样式如下:

    <Style x:Key="DirectLineButtonTemplate" TargetType="{x:Type View:DirectLineButton}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="23"/>
<Setter Property="MinWidth" Value="75"/>
<Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type Button}">
        <Border x:Name="MyBorder"  
               CornerRadius="2" 
               BorderThickness="2"
               Background="Gold"
               BorderBrush="Gray">
        <ContentPresenter Margin="2"
             HorizontalAlignment="Center"
             VerticalAlignment="Center"
             RecognizesAccessKey="True"/>
        </Border>
        <ControlTemplate.Triggers>
        <Trigger Property="View:DirectLineButton.State" Value="DirectLineAvailable">
            <Setter TargetName="MyBorder" Property="Background" Value="Gold"/>
        </Trigger>
        <Trigger Property="View:DirectLineButton.State" Value="DirectLineIdle">
            <Setter  TargetName="MyBorder" Property="Background" Value="Silver"/>
        </Trigger>
        <Trigger Property="View:DirectLineButton.State" Value="DirectLineBusy">
            <Setter  TargetName="MyBorder" Property="Background" Value="Green"/>
        </Trigger>
        <Trigger Property="View:DirectLineButton.State" Value="DirectLineCalled">
            <Setter  TargetName="MyBorder" Property="Background" Value="LightBlue"/>
        </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    </Setter.Value>
</Setter>
</Style>

现在,我需要通过定义 Rectangle 的样式来复制这个想法。不幸的是,当我尝试为矩形定义 ControlTemplate 时,WPF 会标记一条错误消息,您能建议解决此问题的方法吗?请参阅下面的代码,了解我正在尝试的内容:

    <Style x:Key="MyRectangleTemplate" TargetType="{x:Type Rectangle}">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="23"/>
<Setter Property="MinWidth" Value="75"/>
<Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type Rectangle}">
        <Border x:Name="MyBorder"  
               CornerRadius="2" 
               BorderThickness="2"
               Background="Gold"
               BorderBrush="Gray">
        <ContentPresenter Margin="2"
             HorizontalAlignment="Center"
             VerticalAlignment="Center"
             RecognizesAccessKey="True"/>
        </Border>
        <ControlTemplate.Triggers>
        <Trigger Property="View:DirectLineButton.State" Value="DirectLineAvailable">
            <Setter TargetName="MyBorder" Property="Background" Value="Gold"/>
        </Trigger>
        <Trigger Property="View:DirectLineButton.State" Value="DirectLineIdle">
            <Setter  TargetName="MyBorder" Property="Background" Value="Silver"/>
        </Trigger>
        <Trigger Property="View:DirectLineButton.State" Value="DirectLineBusy">
            <Setter  TargetName="MyBorder" Property="Background" Value="Green"/>
        </Trigger>
        <Trigger Property="View:DirectLineButton.State" Value="DirectLineCalled">
            <Setter  TargetName="MyBorder" Property="Background" Value="LightBlue"/>
        </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
    </Setter.Value>
</Setter>
</Style>

提前致谢!

【问题讨论】:

    标签: wpf controltemplate rectangles


    【解决方案1】:

    您好,您只需要使用 Border 即可。仅继承 FrameworkElement 的控件可以具有 Template 。但是 Rectangle 、 Line 等是较轻的版本,它们只继承 UIElement 而不是 FrameworkElement。我希望这会有所帮助。结论:矩形没有模板属性

    【讨论】:

    • 其实Rectangle是从FrameworkElement派生出来的。控件模板仅适用于...控件:)
    • 是的,我的错,我有点困惑,这只是 VisualStudio 的错,它为我们提供了如此多的信息,我们不必记住每一件事。
    • @ethicallogics:您能否编辑您的答案以提供正确的继承方案? (完成后我删除此评论)
    【解决方案2】:

    您不能为Rectangle 定义控件模板,因为它不是控件,而是Shape。您只能为派生自Control 的类定义控件模板。

    【讨论】:

      【解决方案3】:

      你应该
      1) 使用Style(不是ControlTemplate)来设置圆角边框。
      2)在你的风格中使用Trigger

      以下 Xaml 应该让您更接近目标:

       <Style x:Key="MyRectangleStyle" TargetType="{x:Type Rectangle}">
             <Setter Property="SnapsToDevicePixels" Value="true"/>
             <Setter Property="OverridesDefaultStyle" Value="true"/>
             <Setter Property="MinHeight" Value="23"/>
             <Setter Property="MinWidth" Value="75"/>
              <Setter Property="Fill" Value="Blue"/>
      
             <Setter Property="RadiusX" Value="2" />
             <Setter Property="RadiusY" Value="2" />
      
        <Style.Triggers>
          <DataTrigger Binding="{Binding DirectLineState}" 
                              Value="{x:Static l:DLS.Available}">
              <Setter Property="Fill" Value="Gold"/>
          </DataTrigger>
          <DataTrigger Binding="{Binding DirectLineState}" 
                              Value="{x:Static l:DLS.Idle}" >
              <Setter Property="Fill" Value="Silver"/>
          </DataTrigger >
          <DataTrigger Binding="{Binding DirectLineState}"                            
                               Value="{x:Static l:DLS.Available}">
              <Setter Property="Fill" Value="Green"/>
          </DataTrigger >
          <DataTrigger Binding="{Binding DirectLineState}" 
                               Value="{x:Static l:DLS.Called}">
              <Setter  Property="Fill" Value="LightBlue"/>
          </DataTrigger >
        </Style.Triggers>
      </Style>
      

      (请注意:
      1) 我更改了“MyRectangleStyle”的键。
      2) 如果您希望这个Style 成为默认Style,不要给它一个Key,而只是一个TargetType...
      3) ...或将Key 设置为"{x:Type Rectangle}"。 msdn 似乎更喜欢这种方式。
      顺便说一句:您不应该在公共属性上使用 DataTriggers 而不是 Triggers 吗?但我不知道您的应用程序的整个架构。 )

      Rq :要使上面的代码正常工作,您需要 :
      1) 一个名为 DirectLineState 的公共财产在更改时提高 NotifyPropertyChanged
      2) 一个名为 DLS 的 enum 定义在项目的单独文件(如类)中
      3)您需要“l”作为您的项目名称空间。

           <xmlns:l="clr-namespace:MyProjectNameSpace" >   
      

      4) 分配Style 并为Rectangle 设置正确的DataContext

      【讨论】:

      • 感谢您的回复。我已经尝试过您的方法,并且在启动时根据初始状态设置了正确的背景颜色。但是,当我将关联值更改为组件的“状态”依赖属性时,背景颜色保持不变(即,它不会更新)。在我看来,我在这里错过了最后一步,有什么想法吗?
      • 1) 您必须检查 DataContext 是否正确。为了确保您的测试只需给您的矩形一个名称并在窗口构造函数中分配 DataContext 。 2)正如我所说,我不明白你的按钮模板是如何工作的:你应该使用 DataTrigers。我更新了我的答案,现在它可以工作了(我测试过)。
      • 您好,抱歉回复晚了!我原来的帖子实际上是代表一位遇到问题的同事发表的。他最终通过使用按钮而不是矩形组装自定义控件来解决这个问题。再次感谢您的帮助!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-08
      • 1970-01-01
      • 2015-11-10
      • 2015-09-07
      • 2012-03-05
      • 1970-01-01
      相关资源
      最近更新 更多