1

假设您正在WPF中开发一个自定义控件,该控件内部包含一些其他基本控件。为简单起见,假设它包含 2 个按钮

现在你想在你的应用程序中使用这个自定义控件,但你想重新设置它的样式。

情况1

如果在自定义控件定义中,两个按钮具有相同的样式(wpf 默认)并且您想重新设置两者的样式,则应该很容易:

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

案例二

如果在自定义控件定义中,两个按钮具有相同的样式(wpf 默认),但您想用两种不同的样式重新设置它们的样式,那么解决它的最佳方法是什么?

案例 3

如果在自定义控件定义中,两个按钮具有相同的样式,即引用自定义控件中定义的样式,并且您想重新设置它们的样式,那么解决它的最佳方法是什么?

预先感谢您的所有帮助

4

1 回答 1

5

您可以在自定义控件中定义 2 个不同的Style属性并将它们绑定到各个按钮的 Style 属性,从而允许客户端彼此独立地设置两个控件的样式。

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 控件中的其他 Style 属性。

现在您可以像在任何 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 个按钮共享相同的样式。

更新

您不必将FirstButtonStyleSecondButtonStyle属性定义为依赖属性。重要的是,按钮样式属性的内部绑定会在其值更改时更新。您可以通过在用户控件中实现INotifyPropertyChanged接口并在属性设置器中引发OnPropertyChanged事件来完成此操作。

您还可以为用户控件的构造函数中的 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));
      }
    }
  }
}
于 2009-03-02T23:29:11.130 回答