C# wpf中自定义控件的默认样式

C# wpf中自定义控件的默认样式,c#,wpf,C#,Wpf,我想在wpf中设计一个灵活的imagebutton。 首先,我在名称空间“ImageButton”中创建一个WPF自定义控件库,如下所示: namespace ImageButton { public class ImageButton : Button { static ImageButton() { DefaultStyleKeyProperty.OverrideMetadata(typeof(Image

我想在wpf中设计一个灵活的imagebutton。
首先,我在名称空间“ImageButton”中创建一个WPF自定义控件库,如下所示:

namespace ImageButton
{

     public class ImageButton : Button
     {

         static ImageButton()
         {
              DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
         }


          #region DisplayMode
          [System.ComponentModel.Category("ImageButton")]

          public ImageDisplayMode DisplayMode
          {
              get { return (ImageDisplayMode)GetValue(DisplayModeProperty); }
              set { SetValue(DisplayModeProperty, value); }
          }

           public static readonly DependencyProperty DisplayModeProperty =
        DependencyProperty.Register("DisplayMode", typeof(ImageDisplayMode), typeof(ImageButton), new FrameworkPropertyMetadata(ImageDisplayMode.ImageAboveText), displaymodevalidate);

          public static bool displaymodevalidate(object value)
          {
                 return value is ImageDisplayMode;
          }


           #endregion

      }
}
public enum ImageDisplayMode
{
    ImageAboveText = 1,
    TextAboveImage = 2,
    ImageBeforeText = 3,
    TextBeforeImage = 4
}
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ImageButton">
    <Style x:Name="style1" TargetType="{x:Type local:ImageButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Button Background="Transparent">
                        <Grid>
                             <Grid.ColumnDefinitions>
                                  <ColumnDefinition/>
                                  <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                  <RowDefinition/>
                                  <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Image Grid.ColumnSpan="2" Name="img1" Width="{TemplateBinding ImageWidth}" Stretch="{TemplateBinding ImageStretch}" Height="{TemplateBinding ImageHeight}"  Source="{TemplateBinding Image}"/>
                            <TextBlock Grid.ColumnSpan="2" Grid.Row="1" Name="lbl1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Text="{TemplateBinding Text}"/>

                        </Grid>
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
<Grid.Triggers>
    <Trigger Property="DisplayMode" Value="2">
        <Setter Property="Grid.Row" TargetName="lbl1" Value="0"/>
        <Setter Property="Grid.Row" TargetName="img1" Value="1"/>
    </Trigger>
</Grid.Triggers>
在名称空间“ImageButton”中,我定义了一个名为“ImageDisplayMode”的枚举,如下所示:

namespace ImageButton
{

     public class ImageButton : Button
     {

         static ImageButton()
         {
              DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
         }


          #region DisplayMode
          [System.ComponentModel.Category("ImageButton")]

          public ImageDisplayMode DisplayMode
          {
              get { return (ImageDisplayMode)GetValue(DisplayModeProperty); }
              set { SetValue(DisplayModeProperty, value); }
          }

           public static readonly DependencyProperty DisplayModeProperty =
        DependencyProperty.Register("DisplayMode", typeof(ImageDisplayMode), typeof(ImageButton), new FrameworkPropertyMetadata(ImageDisplayMode.ImageAboveText), displaymodevalidate);

          public static bool displaymodevalidate(object value)
          {
                 return value is ImageDisplayMode;
          }


           #endregion

      }
}
public enum ImageDisplayMode
{
    ImageAboveText = 1,
    TextAboveImage = 2,
    ImageBeforeText = 3,
    TextBeforeImage = 4
}
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ImageButton">
    <Style x:Name="style1" TargetType="{x:Type local:ImageButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Button Background="Transparent">
                        <Grid>
                             <Grid.ColumnDefinitions>
                                  <ColumnDefinition/>
                                  <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                  <RowDefinition/>
                                  <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Image Grid.ColumnSpan="2" Name="img1" Width="{TemplateBinding ImageWidth}" Stretch="{TemplateBinding ImageStretch}" Height="{TemplateBinding ImageHeight}"  Source="{TemplateBinding Image}"/>
                            <TextBlock Grid.ColumnSpan="2" Grid.Row="1" Name="lbl1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Text="{TemplateBinding Text}"/>

                        </Grid>
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
<Grid.Triggers>
    <Trigger Property="DisplayMode" Value="2">
        <Setter Property="Grid.Row" TargetName="lbl1" Value="0"/>
        <Setter Property="Grid.Row" TargetName="img1" Value="1"/>
    </Trigger>
</Grid.Triggers>
并对Generic.xaml文件进行如下修改:

namespace ImageButton
{

     public class ImageButton : Button
     {

         static ImageButton()
         {
              DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
         }


          #region DisplayMode
          [System.ComponentModel.Category("ImageButton")]

          public ImageDisplayMode DisplayMode
          {
              get { return (ImageDisplayMode)GetValue(DisplayModeProperty); }
              set { SetValue(DisplayModeProperty, value); }
          }

           public static readonly DependencyProperty DisplayModeProperty =
        DependencyProperty.Register("DisplayMode", typeof(ImageDisplayMode), typeof(ImageButton), new FrameworkPropertyMetadata(ImageDisplayMode.ImageAboveText), displaymodevalidate);

          public static bool displaymodevalidate(object value)
          {
                 return value is ImageDisplayMode;
          }


           #endregion

      }
}
public enum ImageDisplayMode
{
    ImageAboveText = 1,
    TextAboveImage = 2,
    ImageBeforeText = 3,
    TextBeforeImage = 4
}
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ImageButton">
    <Style x:Name="style1" TargetType="{x:Type local:ImageButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Button Background="Transparent">
                        <Grid>
                             <Grid.ColumnDefinitions>
                                  <ColumnDefinition/>
                                  <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                  <RowDefinition/>
                                  <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Image Grid.ColumnSpan="2" Name="img1" Width="{TemplateBinding ImageWidth}" Stretch="{TemplateBinding ImageStretch}" Height="{TemplateBinding ImageHeight}"  Source="{TemplateBinding Image}"/>
                            <TextBlock Grid.ColumnSpan="2" Grid.Row="1" Name="lbl1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Text="{TemplateBinding Text}"/>

                        </Grid>
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
<Grid.Triggers>
    <Trigger Property="DisplayMode" Value="2">
        <Setter Property="Grid.Row" TargetName="lbl1" Value="0"/>
        <Setter Property="Grid.Row" TargetName="img1" Value="1"/>
    </Trigger>
</Grid.Triggers>

上述代码的结果如下图所示:

[图片]
正文

我想: 当我更改imagebutton的“DisplayMode”属性的值时,对于每个可能的值,控件更改为以下形式:

1------------------------------------------
[图片]
正文

2------------------------------------------
文本
[图片]

3------------------------------------------
[图像]文本

4--------------------
文本[图像]

我想,我必须在Generic.xaml代码中定义网格中的触发器,如下所示:

namespace ImageButton
{

     public class ImageButton : Button
     {

         static ImageButton()
         {
              DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
         }


          #region DisplayMode
          [System.ComponentModel.Category("ImageButton")]

          public ImageDisplayMode DisplayMode
          {
              get { return (ImageDisplayMode)GetValue(DisplayModeProperty); }
              set { SetValue(DisplayModeProperty, value); }
          }

           public static readonly DependencyProperty DisplayModeProperty =
        DependencyProperty.Register("DisplayMode", typeof(ImageDisplayMode), typeof(ImageButton), new FrameworkPropertyMetadata(ImageDisplayMode.ImageAboveText), displaymodevalidate);

          public static bool displaymodevalidate(object value)
          {
                 return value is ImageDisplayMode;
          }


           #endregion

      }
}
public enum ImageDisplayMode
{
    ImageAboveText = 1,
    TextAboveImage = 2,
    ImageBeforeText = 3,
    TextBeforeImage = 4
}
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ImageButton">
    <Style x:Name="style1" TargetType="{x:Type local:ImageButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Button Background="Transparent">
                        <Grid>
                             <Grid.ColumnDefinitions>
                                  <ColumnDefinition/>
                                  <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                  <RowDefinition/>
                                  <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Image Grid.ColumnSpan="2" Name="img1" Width="{TemplateBinding ImageWidth}" Stretch="{TemplateBinding ImageStretch}" Height="{TemplateBinding ImageHeight}"  Source="{TemplateBinding Image}"/>
                            <TextBlock Grid.ColumnSpan="2" Grid.Row="1" Name="lbl1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Text="{TemplateBinding Text}"/>

                        </Grid>
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
<Grid.Triggers>
    <Trigger Property="DisplayMode" Value="2">
        <Setter Property="Grid.Row" TargetName="lbl1" Value="0"/>
        <Setter Property="Grid.Row" TargetName="img1" Value="1"/>
    </Trigger>
</Grid.Triggers>

请告诉我:
我怎么做


非常感谢

将触发器添加到您的样式中(即,

也就是说,类似这样的事情:

<Style.Triggers> 
    <Trigger Property="DisplayMode" Value="2"> 
        <Setter Property="Grid.Row" TargetName="lbl1" Value="0"/> 
        <Setter Property="Grid.Row" TargetName="img1" Value="1"/> 
    </Trigger> 
</Style.Triggers> 

谢谢你的支持……
我将触发器移动到ControlTemplate.triggers,并将Trigger.Value从“2”更改为“ImageOverText”(我的自定义枚举项之一),如下所示:

namespace ImageButton
{

     public class ImageButton : Button
     {

         static ImageButton()
         {
              DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
         }


          #region DisplayMode
          [System.ComponentModel.Category("ImageButton")]

          public ImageDisplayMode DisplayMode
          {
              get { return (ImageDisplayMode)GetValue(DisplayModeProperty); }
              set { SetValue(DisplayModeProperty, value); }
          }

           public static readonly DependencyProperty DisplayModeProperty =
        DependencyProperty.Register("DisplayMode", typeof(ImageDisplayMode), typeof(ImageButton), new FrameworkPropertyMetadata(ImageDisplayMode.ImageAboveText), displaymodevalidate);

          public static bool displaymodevalidate(object value)
          {
                 return value is ImageDisplayMode;
          }


           #endregion

      }
}
public enum ImageDisplayMode
{
    ImageAboveText = 1,
    TextAboveImage = 2,
    ImageBeforeText = 3,
    TextBeforeImage = 4
}
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ImageButton">
    <Style x:Name="style1" TargetType="{x:Type local:ImageButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:ImageButton}">
                    <Button Background="Transparent">
                        <Grid>
                             <Grid.ColumnDefinitions>
                                  <ColumnDefinition/>
                                  <ColumnDefinition/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                  <RowDefinition/>
                                  <RowDefinition/>
                            </Grid.RowDefinitions>
                            <Image Grid.ColumnSpan="2" Name="img1" Width="{TemplateBinding ImageWidth}" Stretch="{TemplateBinding ImageStretch}" Height="{TemplateBinding ImageHeight}"  Source="{TemplateBinding Image}"/>
                            <TextBlock Grid.ColumnSpan="2" Grid.Row="1" Name="lbl1" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Text="{TemplateBinding Text}"/>

                        </Grid>
                    </Button>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>
<Grid.Triggers>
    <Trigger Property="DisplayMode" Value="2">
        <Setter Property="Grid.Row" TargetName="lbl1" Value="0"/>
        <Setter Property="Grid.Row" TargetName="img1" Value="1"/>
    </Trigger>
</Grid.Triggers>
编辑前:

 <Trigger Property="DisplayMode" Value="2"> 
     <Setter Property="Grid.Row" TargetName="lbl1" Value="0"/> 
     <Setter Property="Grid.Row" TargetName="img1" Value="1"/> 
 </Trigger> 

编辑后:

 <Trigger Property="DisplayMode" Value="ImageAboveText">
     <Setter Property="Grid.Row" TargetName="lbl1" Value="0"/> 
     <Setter Property="Grid.Row" TargetName="img1" Value="1"/>
 </Trigger>

我的问题成功地解决了……

谢谢。

谢谢,我测试了您的答案,但有错误:我将触发器移动到controltemplate,错误已解决,但无法正常工作。