Wpf CustomButton工具栏样式

时间:2010-09-16 07:54:34

标签: wpf user-controls styles

我创建了一个UserControl来制作ImageButton。但是我用Button替换了UserControl项目。

<Button x:Class="myimagebutton"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:imagebutton">

    <Grid x:Name="grdButton">
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Image Grid.Column="0"
               x:Name="btnImage"
               HorizontalAlignment="Left"
               VerticalAlignment="Center">
        </Image>
        <TextBlock Grid.Column="1"
                   TextWrapping="Wrap"
                   Text="{Binding Text}"
                   VerticalAlignment="Center"
                   Margin="2 0 2 0" />
    </Grid>
</Button>

现在我想将工具栏按钮样式应用于我的按钮,如果此按钮位于工具栏中。我已阅读本文link text并将此

If Me.Style Is Nothing AndAlso TypeOf Me.Parent Is ToolBar Then
   Me.Style = DirectCast(FindResource(ToolBar.ButtonStyleKey), Style)
End If

在我的Codebehind中。

之后我将我的Button放在工具栏中,另一个放在工具栏中进行测试。但Button始终获得默认样式。在调试后我发现Me.Parent总是没有。那么现在我的问题是如何获得我的按钮在工具栏中的信息?

1 个答案:

答案 0 :(得分:0)

我很难理解你所描述的内容,但经过几次阅读后我觉得我明白了。

到目前为止我是对的吗?

如果是这样,您想知道为什么您的按钮有图像

关于你的描述的几点指示让我失望,这可能就是为什么到目前为止你还没有看到别人发表你的问题的答案。

  

我用一个按钮替换了UserControl项目

基本上你所做的是创建可能继承自Button的新控件。您可能已经开始使用UserControl但是为了替换XAML中的根项,您还必须确保您的类型myimagebutton也从Button继承。这就是XAML的工作原理,学习如何以这种方式解释它将有助于人们理解你在做什么。

通常继承自Button不是开发人员如何覆盖WPF中按钮的视觉样式,主要是因为WPF不支持有时被称为visual inheritance的概念,还有其他合适的方法可以用于以不同的方式解决问题。相反,继承主要用于需要对现有控件类进行行为修改或添加时。这就是说有一些方法可以通过使用与ASP.NET中的内容页面和母版页类似的内容控件来模拟可视继承,但我认为这有点超出了您的示例的范围。另外,如果你要继续使用继承模型,你需要确保在你的代码中你在静态构造函数中设置正确的默认样式,所以在你的按钮后面发布代码也会有所帮助。

我相信你的例子不起作用的原因是因为ToolBar专门查看控件的类型而不管继承,以便应用它的自定义工具栏样式。在您的情况下,您的控件是myimagebutton类型而不是Button类型,因此ToolBar不会设置样式,ToolBar通常根据使用两种可能类型的调用的控件类型直接设置Style属性。

element.SetResourceReference(FrameworkElement.StyleProperty, styleKey);
element.DefaultStyleKey = styleKey;

BTW,在你的情况下,我认为只有第二行是由ToolBar控件执行的,而此时styleKey被定义为null。

现在不是首先从Button继承,而是为了为按钮创建一个新的ControlTemplate或DataTemplate并分别通过使用样式分配到Template或ContentTemplate属性,你可能会更好。通过这种方式,您仍然可以处理按钮,而样式则会改变视觉属性。

<Window x:Class="HeaderedContentControlTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="252"
        Width="372">
    <Window.Resources>
        <Style TargetType="{x:Type Label}">
            <Setter Property="Background"
                    Value="Orange" />
        </Style>

        <DataTemplate x:Key="ImageButtonDataTemplate">
            <Grid x:Name="grdButton">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>

                <Image Grid.Column="0"
                       HorizontalAlignment="Left"
                       VerticalAlignment="Center">
                </Image>
                <TextBlock Grid.Column="1"
                           TextWrapping="Wrap"
                           Text="{Binding}"
                           VerticalAlignment="Center"
                           Margin="2 0 2 0"
                           Background="Pink" />
            </Grid>
        </DataTemplate>

        <Style x:Key="ImageButtonStyle"
               TargetType="{x:Type Button}">
            <Setter Property="ContentTemplate"
                    Value="{StaticResource ImageButtonDataTemplate}" />
        </Style>

    </Window.Resources>
    <Grid Margin="11">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <ToolBar>
            <Button Style="{StaticResource ImageButtonStyle}"
                    Content="Some Text" />
        </ToolBar>

        <Button Grid.Row="1"
                Style="{StaticResource ImageButtonStyle}"
                VerticalAlignment="Center"
                HorizontalAlignment="Center"
                Content="Some Text" />
    </Grid>
</Window>

使用ContentTemplate,您可以重新定义Button的内部内容,而不会丢失所有特殊的按钮状态转换以及您通常希望保留的其他细节。

请参阅MSDN论坛上的this related post,这也解释了在向ToolBar添加包含按钮的StackPanel时的类似行为。