代码之家  ›  专栏  ›  技术社区  ›  Drake

如何重新设置嵌套在自定义控件中的控件的样式?

  •  1
  • Drake  · 技术社区  · 17 年前

    假设您正在开发一个 在WPF中,内部包含一些其他基本控件。 为了保持简单,假设它包含两个按钮 .

    现在您想在应用程序中使用此自定义控件,但您想 重塑风格 有一点。

    案例1

    <mc:MyControl>
       <mc:MyControl.Resources>
          <Style x:Key={x:Type Button}, TargetType={x:Type Button}>
             <!-- Insert the new style here -->
          </Style>
       </mc:MyControl.Resources>
    <mc:MyControl>
    

    案例2

    如果在自定义控件定义中,两个按钮具有相同的样式(wpf默认值),但您希望 ,最好的解决方法是什么?

    案例3

    引用自定义控件内定义的样式的 ,你想重新设计它们,最好的解决方法是什么?

    提前感谢您的帮助

    1 回复  |  直到 17 年前
        1
  •  5
  •   Enrico Campidoglio    17 年前

    您可以定义两个不同的 风格 自定义控件中的属性和 ,从而允许客户端彼此独立地设置两个控件的样式。

    XAML文件:

    <UserControl x:Class="MyNamespace.MyControl"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Name="MyControl">
      <StackPanel>
        <Button Name="FirstButton"
                Style={Binding ElementName=MyControl, Path=FirstButtonStyle}
                Content="First Button" />
        <Button Name="SecondButton"
                Style={Binding ElementName=MyControl, Path=SecondButtonStyle}
                Content="Second Button" />
      </StackPanel>
    </UserControl>
    

    using System;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace MyNamespace
    {
      [StyleTypedProperty(
      Property = "FirstButtonStyle",
      StyleTargetType = typeof(Button))]
      [StyleTypedProperty(
      Property = "SecondButtonStyle",
      StyleTargetType = typeof(Button))]
      public partial class MyControl : UserControl
      {
        public static readonly DependencyProperty FirstButtonStyleProperty =
          DependencyProperty.Register(
            "FirstButtonStyle",
            typeof(Style),
            typeof(MyControl)
          );
    
        public Style FirstButtonStyle
        {          
          get { return (Style)GetValue(FirstButtonStyleProperty); }
          set { SetValue(FirstButtonStyleProperty, value); }
        }
    
    
        public static readonly DependencyProperty SecondButtonStyleProperty =
          DependencyProperty.Register(
            "SecondButtonStyle",
            typeof(Style),
            typeof(MyControl)
          );
    
        public Style SecondButtonStyle
        {          
          get { return (Style)GetValue(SecondButtonStyleProperty); }
          set { SetValue(SecondButtonStyleProperty, value); }
        }
      }
    }
    

    最好将这两个属性实现为依赖项属性,因为这将使它们符合标准WPF控件中的其他样式属性。

    现在,您可以像在任何WPF控件中一样设置按钮的样式:

    <Window 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:local="clr-namespace:MyNamespace"
      Title="MyControl Sample" 
      Height="300" 
      Width="300">
      <Window.Resources>
        <Style x:Key="GreenButton" TargetType="{x:Type Button}">
          <Setter Property="Background" Value="Green" />
        </Style>
        <Style x:Key="RedButton" TargetType="{x:Type Button}">
          <Setter Property="Background" Value="Red" />
        </Style>
      </Windows.Resources>
      <StackPanel>
        <local:MyControl FirstButtonStyle="{StaticResource GreenButton}"
                         SecondButtonStyle="{StaticResource RedButton}" />
      </StackPanel>
    </Window>
    

    或者你可以有两个按钮 在自定义控件中,绑定到两个内部控件的Style属性。

    使现代化

    您不必定义 属性作为依赖项属性。重要的是,按钮的内部绑定 每当属性的值更改时,属性都会更新。您可以通过实现 用户控件中的接口,并提高 属性设置器中的事件。

    还可以为用户控件的构造函数中的2个属性指定“默认样式”。以下是一个例子:

    using System;
    using System.ComponentModel;
    using System.Windows;
    using System.Windows.Controls;
    
    namespace MyNamespace
    {
      [StyleTypedProperty(
      Property = "FirstButtonStyle",
      StyleTargetType = typeof(Button))]
      [StyleTypedProperty(
      Property = "SecondButtonStyle",
      StyleTargetType = typeof(Button))]
      public partial class MyControl : UserControl, INotifyPropertyChanged
      {
        private Style firstButtonStyle;
        private Style secondButtonStyle;
    
        public MyControl()
        {
          Style defaultStyle = new Style();
          // assign property setters to customize the style
    
          this.FirstButtonStyle = defaultStyle;
          this.SecondButtonStyle = defaultStyle; 
        }
    
        public Style FirstButtonStyle
        {          
          get { return firstButtonStyle; }
          set
          {
             firstButtonStyle = value;
             OnPropertyChanged("FirstButtonStyle");
          }
        }
    
        public Style SecondButtonStyle
        {          
          get { return secondButtonStyle; }
          set
          {
             secondButtonStyle = value;
             OnPropertyChanged("SecondButtonStyle");
          }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
          if (PropertyChanged != null)
          {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
          }
        }
      }
    }