wpf 在 XAML 中为矩形定义控件模板

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13477598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:18:20  来源:igfitidea点击:

Defining a control template for a rectangle in XAML

wpfcontroltemplaterectangles

提问by Nacho1984

In my current project, I have this XAML file where I define the visual style that must be applied to different types of custom widgets.

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

For example, the style for a 'DirectLineButton' (a custom class that inherits from WPF's Button) is as follows:

例如,“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>

Now, I need to replicate this idea by defining the style for a Rectangle. Unfortunately, WPF flags an error message when I try to define a ControlTemplate for a rectangle, can you suggest a workaround for this? See the code below of what I'm trying to attempt:

现在,我需要通过定义 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>

Thanks in advance!

提前致谢!

回答by yo chauhan

Hi you will have to do it with Border only.Controls that inherits FrameworkElement only can have Template . But Rectangle , Line etc are lighter versions they inherits only UIElement not FrameworkElement.I hope this will help. Conclusion: Rectange do not have Template property

嗨,您必须仅使用 Border 来执行此操作。继承 FrameworkElement 的控件只能具有 Template 。但是 Rectangle 、 Line 等是较轻的版本,它们仅继承 UIElement 而不是 FrameworkElement。我希望这会有所帮助。结论:矩形没有模板属性

回答by Adi Lester

You can't define a control template for a Rectangle, since it's not a control, but a Shape. You can only define a control template for classes derived from Control.

您不能为 a 定义控件模板Rectangle,因为它不是控件,而是Shape. 您只能为从Control.

回答by GameAlchemist

You should
1) use a Style(not a ControlTemplate) to have rounded borders.
2) Use a Triggerinside your style.

您应该
1) 使用 a Style(而不是 a ControlTemplate)来获得圆角边框。
2)使用Trigger你的风格。

The following Xaml should get you closer from your goal :

以下 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>

(notice that :
1) i changed the key for "MyRectangleStyle".
2) If you want this Styleto be the default Style, do not give it a Key, but just a TargetType...
3) ...OR set the Keyto "{x:Type Rectangle}". msdn seems to prefer that way.
btw : shouldn't you be using DataTriggers on public properties instead of Triggers ? but i don't know the whole architecture of your application. )

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

Rq : for the code above to work, you need :
1) a public proprety called DirectLineState raising NotifyPropertyChangedon change.
2) an enumcalled DLS defined in a separate file (like a class) in your project
3) you need "l" to be your project NameSpace.

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

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

4) Assign Styleand set proper DataContextfor the Rectangle

4)分配Style和设置适当DataContextRectangle