如何确定自定义控件是否在工具栏中?

发布于 2024-09-19 19:23:25 字数 1604 浏览 3 评论 0原文

我已经创建了一个 UserControl 来制作 ImageButton

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

现在我想应用 默认工具栏按钮样式到我的按钮(如果此按钮位于工具栏中)。我已阅读这篇文章链接文本 并将其

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

放在我的代码后面。

之后,作为测试,我将按钮放入工具栏中,并将另一个按钮放在工具栏中以对其进行测试。但按钮总是获得默认样式,而不是我试图设置的样式。

调试后我发现 Me.Parent 始终是 Nothing。现在我的问题是:如何获取我的按钮是否在工具栏中的信息?

i have created a UserControl to make an ImageButton:

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

now i want to apply the default Toolbar Button Style to my Button if this Button is in a Toolbar. I have read this article link text and put this

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

in my Code behind.

After that as a test I put my Button both in a Toolbar and another out of the Toolbar to test it. But the Button always get the default style, not the style I am trying to set.

After debugging i find out that Me.Parent is always Nothing. So now is my question: how i get the information that my button is in a toolbar or not?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

醉生梦死 2024-09-26 19:23:25

我很难准确理解你所描述的内容,但读了几次后我想我明白了。

到目前为止我是对的吗?

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

关于您的描述的一些提示让我失望,这可能是您迄今为止没有看到其他人为您的问题发布答案的原因。

我用按钮替换了 UserControl 项

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

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

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

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

顺便说一句,在您的情况下,我相信只有第二行由 ToolBar 控件执行,并且此时的 styleKey 被定义为 null。

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

<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 允许您重新定义按钮的内部内容,而不会丢失所有特殊按钮状态转换和您通常希望保留的其他细节。

请参阅此相关帖子 也解释了将包含按钮的 StackPanel 添加到工具栏时的类似行为。

I'm having some difficulty understanding exactly what you are describing but after reading it through a few times I think I understand.

Am I right so far?

If so, you are wondering then why your button has an image

A few pointers about your description that threw me off and is probably the reason why you haven't seen anybody else post an answer for your question thus far.

i replaced the the UserControl Item with a Button

Essentially what you have done is created new control that likely inherits from Button. You might have started off with a UserControl but in order to replace the root item in XAML you would also have to make sure your type myimagebutton inherits from Button as well. This is just how XAML works and learning how to explain it this way will help people understand what you are doing.

Normally inheriting from Button is not how developers override the visual style of a button in WPF mainly because WPF doesn't support the concept of what is sometimes referred to as visual inheritance and also there are other suitable methods that can be used to solve the problem in a different way. Instead inheritance is mainly reserved for when behavioral modifications or additions need to be made to an existing control class. This being said there are ways to simulate visual inheritance through the use of content controls that work similar to content pages and master pages in ASP.NET but I think this is a bit outside of the scope of your example. Also if you are to pursue the inheritance model you will need to make sure that in your code behind that you are setting the correct default style in the static constructor so posting your code behind for your button would help too.

I believe the reason why your example isn't working is because the ToolBar specifically looks at the types of controls irrespective inheritance in order to to apply it's custom toolbar styles. In your case your control is of type myimagebutton and not Button so the style is not set by the ToolBar which normally directly sets the Style property based on the type of the control using the two potential types of calls.

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

BTW, in your case I believe only the second line is performed by the ToolBar control and styleKey at that point is defined as null.

Now instead of inheriting from Button in the first place you would probably be better off just to create a new ControlTemplate or a DataTemplate for your button and assigning into the Template or ContentTemplate property respectively through the use of a style. This way you are still always dealing with a button and the style is what changes the visual properties.

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

Using the ContentTemplate allows you to redefine the inner contents of the Button without loosing all of the special button state transitions and other niceties you would normally like to keep.

See this related post on MSDN Forums that also explains similar behavior when adding a StackPanel containing buttons to a ToolBar.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文