在样式中设置控件内容不起作用

时间:2016-01-08 15:01:21

标签: c# wpf xaml user-controls

我尝试创建自定义旋转控件。它必须在中间包含2个按钮(左和右)+文本(文本块)。 所以我创造了 的.xaml:

<UserControl x:Class="...CustomSpinControl"
 ....
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <RepeatButton Grid.Column="0" Command="{Binding ShiftLeftLowCommand}" Style="{Binding LeftButtonStyle, Mode=OneTime}"/>
    <TextBlock>
      <TextBox Text="{Binding Value}"/>
      <TextBox IsReadOnly="True" />
    </TextBlock>
    <RepeatButton Grid.Column="2" Command="{Binding ShiftRightLowCommand}" Style="{Binding RightButtonStyle, Mode=OneWay}"/>
  </Grid>
</UserControl>

和xaml.cs

namespace UserControls
{
    [StyleTypedProperty (
    Property = "LeftButtonStyle",
    StyleTargetType = typeof (RepeatButton))]
    [StyleTypedProperty (
    Property = "RightButtonStyle",
    StyleTargetType = typeof (RepeatButton))]

    public partial class CustomSpinControl : INotifyPropertyChanged
    {
#region LowShiftValue
        public static readonly DependencyProperty LowShiftValueProperty =
          DependencyProperty.Register ("LowShiftValue", typeof (int), typeof (CustomSpinControl),
          new FrameworkPropertyMetadata (1, OnLowShiftValueChanged));

        public static void OnLowShiftValueChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((CustomSpinControl)d).RaisePropertyChanged ("LowShiftValue");
        }

        public int LowShiftValue
        {
            get { return (int)GetValue (LowShiftValueProperty); }
            set { SetValue (LowShiftValueProperty, value); }
        }
        #endregion
....
}

当我使用控件时,我会创建一个这样的样式

<Style x:Key="RightSpin2" TargetType="RepeatButton" >
      <Setter Property="Content">
        <Setter.Value>
          <Border Background="Transparent" Height="20">
            <Viewbox >
              <Canvas  HorizontalAlignment="Left" Height="56.9355" UseLayoutRounding="False" VerticalAlignment="Top" Width="65.8237">
                <Canvas  Height="56.936" Canvas.Left="0" Canvas.Top="-0.936" Width="65.877">
                  <Path Data="F1M55.876,0.001L0,0.003 0,56.936 55.876,56.936C61.376,56.936,65.876,52.436,65.876,46.936L65.876,10C65.876,4.5,61.376,0.001,55.876,0.001" Fill="BlueViolet" Height="56.936" Canvas.Left="0.001" Canvas.Top="0" Width="65.876"/>
                  <Path Data="F1M0,28.644C0,30.844,1.559,31.744,3.464,30.644L26.131,17.556C28.037,16.456,28.037,14.656,26.131,13.556L3.464,0.47C1.559,-0.629,0,0.27,0,2.47z" Fill="#FF999999" Height="31.113" Canvas.Left="21.128" Canvas.Top="13.147" Width="27.561"/>
                  <Path Data="F1M56.125,0L0,0 0,26.956C36.817,26.518,65.824,25.488,65.824,23.865L65.824,9.735C65.824,4.422,60.939,0,56.125,0" Height="26.956" Canvas.Left="0" Opacity="0.3" Canvas.Top="0" Width="65.824">
                    <Path.Fill>
                      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF97999C" Offset="0"/>
                        <GradientStop Color="#FF97999C" Offset="0.239"/>
                        <GradientStop Color="#FF57585B" Offset="1"/>
                      </LinearGradientBrush>
                    </Path.Fill>
                  </Path>
                </Canvas>
              </Canvas>
            </Viewbox>
          </Border>
        </Setter.Value>
      </Setter>
    </Style>

并放置代码

<UserControls:CustomSpinControl Grid.Row="2" Grid.Column="1"
    LeftButtonStyle="{StaticResource LeftSpin}"
    RightButtonStyle="{StaticResource RightSpin2}">

一切都好。但是只要我使用相同的按钮样式放置第二个控件...只显示最后一个按钮。当我使用不同的(按名称而非内容)样式时,例如RightSpin&amp; RightSpin2然后一切都好了。 有谁能够帮我?

1 个答案:

答案 0 :(得分:0)

问题是你是通过Style Setter设置Content

你在那里Content有一个可视树,只有一个实例。 XAML中的给定控件只能有一个父级。将样式应用于第二个按钮时,Border将重新设置为父级,并从上一个按钮消失。

您正在尝试为每个按钮创建Border的新实例及其内容。将“相同”内容同时应用于多个控件的方法是通过ControlTemplate。应用模板时,会实例化一个新的可视化树,它是模板内容的克隆。

你的Style应该将RepeatButton的Template属性设置为ControlTemplate,其中包含你所拥有的相同内容。

应该这么简单:

<Style x:Key="RightSpin2" TargetType="RepeatButton" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="RepeatButton">
                <Border Background="Transparent" Height="20">
                    <Viewbox >
                        <Canvas  HorizontalAlignment="Left" Height="56.9355" UseLayoutRounding="False" VerticalAlignment="Top" Width="65.8237">
                            <Canvas  Height="56.936" Canvas.Left="0" Canvas.Top="-0.936" Width="65.877">
                                <Path Data="F1M55.876,0.001L0,0.003 0,56.936 55.876,56.936C61.376,56.936,65.876,52.436,65.876,46.936L65.876,10C65.876,4.5,61.376,0.001,55.876,0.001" Fill="BlueViolet" Height="56.936" Canvas.Left="0.001" Canvas.Top="0" Width="65.876"/>
                                <Path Data="F1M0,28.644C0,30.844,1.559,31.744,3.464,30.644L26.131,17.556C28.037,16.456,28.037,14.656,26.131,13.556L3.464,0.47C1.559,-0.629,0,0.27,0,2.47z" Fill="#FF999999" Height="31.113" Canvas.Left="21.128" Canvas.Top="13.147" Width="27.561"/>
                                <Path Data="F1M56.125,0L0,0 0,26.956C36.817,26.518,65.824,25.488,65.824,23.865L65.824,9.735C65.824,4.422,60.939,0,56.125,0" Height="26.956" Canvas.Left="0" Opacity="0.3" Canvas.Top="0" Width="65.824">
                                    <Path.Fill>
                                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                            <GradientStop Color="#FF97999C" Offset="0"/>
                                            <GradientStop Color="#FF97999C" Offset="0.239"/>
                                            <GradientStop Color="#FF57585B" Offset="1"/>
                                        </LinearGradientBrush>
                                    </Path.Fill>
                                </Path>
                            </Canvas>
                        </Canvas>
                    </Viewbox>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>