簡體   English   中英

如何使用BasedOn在Generic.xaml中設置切換按鈕的模板?

[英]How to use BasedOn to template a toggle button in Generic.xaml?

WPF的C#XAML

在我的Generic.xaml中,我有多種形式的樣式:

  <Style x:Key="ToggleButtonStyle12" TargetType="{x:Type ToggleButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Grid>
                        <Path x:Name="path1" Data="{StaticResource InsideQuarter3}" Fill="DarkOrange" Stroke="Black" />
                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" 
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="true">
                            <Trigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
                            </Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
                            </Trigger.ExitActions>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

所有這些切換按鈕之間的唯一區別是路徑定義和填充顏色。

是否可以僅需要提供路徑和填充顏色的方式對這種樣式進行模板化/簡化?

這與以下內容類似:

<Style x:Key="ToggleButtonStyle12" BasedOn(??????)>
    <Setter Property = "Path" Value="InsideQuarter3"/>
    <Setter Property = "Fill" Value="DarkOrange"/>
</Style>

感謝您的任何幫助。

編輯#1好吧,我以為自己有錯–我錯了。 下面的代碼將正確設置“路徑數據”和“填充”屬性。 但是,只有第一個創建的ToggleButton會保留“ MouseOver”和其他ControlTemplate.Triggers。 我需要RingControl中的所有切換按鈕都尊重自己的觸發器。

  public static class ButtonProperties
    {
        public static Color GetMyForegroundColor(DependencyObject obj)
        {
            return (Color)obj.GetValue(MyForegroundColorProperty);
        }

        public static void SetMyForegroundColor(DependencyObject obj, Color value)
        {
            obj.SetValue(MyForegroundColorProperty, value);
        }

        // Using a DependencyProperty as the backing store for MyForegroundColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MyForegroundColorProperty =
            DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));



        public static Geometry GetData(DependencyObject obj)
        {
            return (Geometry)obj.GetValue(DataProperty);
        }

        public static void SetData(DependencyObject obj, Geometry value)
        {
            obj.SetValue(DataProperty, value);
        }

        // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataProperty =
            DependencyProperty.RegisterAttached("Data", typeof(Geometry), typeof(ButtonProperties), new PropertyMetadata(null));



        public static Brush GetFill(DependencyObject obj)
        {
            return (Brush)obj.GetValue(FillProperty);
        }

        public static void SetFill(DependencyObject obj, Brush value)
        {
            obj.SetValue(FillProperty, value);
        }

        // Using a DependencyProperty as the backing store for Fill.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FillProperty =
            DependencyProperty.RegisterAttached("Fill", typeof(Brush), typeof(ButtonProperties), new PropertyMetadata(null));

    }

Generic.xaml-BaseButtonStyle

  <Style x:Key="BaseButtonStyle" TargetType="{x:Type ToggleButton}">
        <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Blue"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Grid>
                    <TextBlock Text="Some Text">
                        <TextBlock.Foreground>
                            <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
                        </TextBlock.Foreground>
                    </TextBlock>

                        <Path x:Name="path1" Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Data)}" 
                              Fill="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.Fill)}" 
                              Stroke="Black"/>

                        <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" 
                                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="true">
                            <Setter TargetName="path1" Property = "Opacity" Value="0.4"/>
                        </Trigger>
                        <Trigger Property="IsChecked" Value="true">
                            <Trigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource Blink_On}"/>
                            </Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <BeginStoryboard Storyboard="{StaticResource Blink_Off}"/>
                            </Trigger.ExitActions>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Generic.xaml-ModifiedButtonStyle1

 <Style x:Key="ModifiedButtonStyle1" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
        <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
        <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc0}" />
        <Setter Property="local:ButtonProperties.Fill" Value="LightGreen"/>
    </Style>
    <Style x:Key="ModifiedButtonStyle2" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
        <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
        <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc45}" />
        <Setter Property="local:ButtonProperties.Fill" Value="LightPink"/>
    </Style>
    <Style x:Key="ModifiedButtonStyle3" TargetType="{x:Type ToggleButton}" BasedOn="{StaticResource BaseButtonStyle}">
        <Setter Property="local:ButtonProperties.MyForegroundColor" Value="Red" />
        <Setter Property="local:ButtonProperties.Data" Value="{StaticResource Arc90}" />
        <Setter Property="local:ButtonProperties.Fill" Value="LightCoral"/>
    </Style>

Generic.xaml-在自定義控件RingControl中使用ModifiedButtonStyles

 <Style TargetType="{x:Type local:RingButtons2}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:RingButtons2}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">

                    <Viewbox>
                        <Grid>
                            <!--Outer Rim -->
                            <Path Data="{StaticResource OuterRim}"  Fill="Silver" Stroke="Black" />
                            <Path Data="{StaticResource OuterWheelBackground}" Fill="White" Stroke="Black" />

                            <ToggleButton x:Name="PART_Button1" Style="{StaticResource ModifiedButtonStyle1}"/>
                            <ToggleButton x:Name="PART_Button2" Style="{StaticResource ModifiedButtonStyle2}"/>
                            <ToggleButton x:Name="PART_Button3" Style="{StaticResource ModifiedButtonStyle3}"/>
  ........................................................
  </Grid>
                        </Viewbox>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

在用戶界面中使用RingControl2:

       <w:RingButtons2/>

似乎單擊RingButtons2控件中的任何位置只會導致第一個定義的切換按鈕做出響應-不會產生任何其他響應。

我該如何解決這個問題,以使每個切換按鈕都獨立於其他按鈕運行,並尊重自己的控制模板觸發器?

再次感謝。

編輯#2

從BaseButtonStyle刪除TextBlock定義后,

 <TextBlock Text="Some Text">
                        <TextBlock.Foreground>
                            <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:ButtonProperties.MyForegroundColor)}" />
                        </TextBlock.Foreground>
                    </TextBlock>

所有工作! 為什么是這樣??

謝謝。

如果目標控件具有可用於這些自定義綁定的依賴項屬性,則可以使用TemplateBinding,這是一個示例:

    <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="Foreground" Value="Blue" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <TextBlock Text="Some Text" Foreground="{TemplateBinding Foreground}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
        <Setter Property="Foreground" Value="Red" />
    </Style>

然后您將這樣引用:

<Grid>
    <Button Style="{StaticResource ModifiedButtonStyle}" />
</Grid>

但是,在上面給出的示例中,您正在模板中使用“路徑”和“填充”,我想它們沒有關聯的屬性。 在這種情況下,您的選擇是創建一個新控件並向其中添加這些屬性,或者最好使用附加屬性。 對於后者,您將創建一個如下所示的附加屬性:

public static class ButtonProperties
{
    public static Color GetMyForegroundColor(DependencyObject obj)
    {
        return (Color)obj.GetValue(MyForegroundColorProperty);
    }

    public static void SetMyForegroundColor(DependencyObject obj, Color value)
    {
        obj.SetValue(MyForegroundColorProperty, value);
    }

    // Using a DependencyProperty as the backing store for MyForegroundColor.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty MyForegroundColorProperty =
        DependencyProperty.RegisterAttached("MyForegroundColor", typeof(Color), typeof(ButtonProperties), new PropertyMetadata(Colors.Black));
}

然后在XAML中引用並覆蓋它:

<Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Blue"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <TextBlock Text="Some Text">
                    <TextBlock.Foreground>
                        <SolidColorBrush Color="{Binding RelativeSource={RelativeSource TemplatedParent},
                            Path=(behaviors:ButtonProperties.MyForegroundColor)}" />
                    </TextBlock.Foreground>
                </TextBlock>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="ModifiedButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
    <Setter Property="behaviors:ButtonProperties.MyForegroundColor" Value="Red" />
</Style>

這些大致相同,只是在第一種情況下,您使用控件中已經存在的現有屬性(或創建一個包含它們的新控件),而在第二種情況下,您聲明並將它們附加到外部現有的控件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM