【问题标题】:Change a button's content in a style?以样式更改按钮的内容?
【发布时间】:2010-11-06 05:59:27
【问题描述】:

我正在尝试做类似的事情:

<Window x:Class="WpfApplication1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid>
        <Button>
            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Content"
                            Value="No mouse over" />
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver"
                                 Value="True">
                            <Setter Property="Content">
                                <Setter.Value>
                                    <CheckBox Content="Mouse is over" />
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </Grid>
</Window>

但是,我收到运行时 XamlParseException 消息:

无法添加类型的内容 'System.Windows.Controls.CheckBox' 到 “System.Object”类型的对象。 对象错误 'System.Windows.Controls.CheckBox

我实际上是在尝试根据外部条件为按钮的内容绘制不同的图标。所以我实际上是在尝试使用 DataTrigger,但上面的示例简化了问题。有什么想法吗?

【问题讨论】:

    标签: c# wpf xaml data-binding styles


    【解决方案1】:

    发生实际错误是因为无法将 Visuals 直接设置为 Setter 值。 不过,您可以通过使用 DataTemplate 设置 ContentTemplate 或通过将内容创建为资源(特定于按钮或位于其他位置)来获得您正在寻找的行为。

    <Button>
        <Button.Resources>
            <CheckBox x:Key="Local_MouseOverContent" Content="Mouse is over" />
        </Button.Resources>
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Content" Value="No mouse over" />
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Content"
                                Value="{StaticResource Local_MouseOverContent}" />
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    
    <Button>
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="Content" Value="No mouse over" />
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="ContentTemplate">
                            <Setter.Value>
                                <DataTemplate DataType="Button">
                                    <CheckBox Content="Mouse is over" />
                                </DataTemplate>
                            </Setter.Value>
                        </Setter>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>
    

    【讨论】:

      【解决方案2】:

      请注意!正是您的示例在 .NET Framework 4 中工作,没有任何更改!!!!

        <Button>
              <Button.Style>
                  <Style TargetType="{x:Type Button}">
                      <Setter Property="Content"
                              Value="No mouse over" />
                      <Style.Triggers>
                          <Trigger Property="IsMouseOver"
                                   Value="True">
                              <Setter Property="Content">
                                  <Setter.Value>
                                      <CheckBox Content="Mouse is over" />
                                  </Setter.Value>
                              </Setter>
                          </Trigger>
                      </Style.Triggers>
                  </Style>
              </Button.Style>
          </Button>
      

      【讨论】:

      • 这真的有效,你!当 Button.Content 属性设置了一个属性时,它停止工作。即&lt;Button Content="initial content" Style="{StaticResource StyleChangeContentOnMouseOver}" /&gt; 只会显示"initial content"
      【解决方案3】:

      如果您正在为应用程序周围的按钮创建通用样式,则使用图像作为资源的方法会出现视觉树冲突。因此,在这种情况下,模板是您唯一的选择。

      【讨论】:

        【解决方案4】:

        警告:这可能不是最好或正确的方法。确保您也阅读了此页面上的其他答案。

        很确定您想在这种情况下使用控制模板。比如:

        <style> <Setter Property="Content"> <Setter.Value> <ControlTemplate> <Image Img="something.jpg" /> </ControlTemplate> </Setter.Value> </Setter> </style>

        并在悬停的触发器中添加一个控制模板。

        这是一个很好的link

        【讨论】:

        • 这行不通。 ControlTemplate 是并且应该用于修改控件的视觉结构和行为,而不是它的内容。此外,除非您还为它设置了 ContentTemplate,否则 ContentProperty 甚至无法呈现 ControlTemplate。
        • 正如摩尔所说,这是行不通的。您需要将 ContentTemplate 属性设置为 DataTemplate。
        • 对不起,我投了你的票,但现在不让我收回。我已经阅读了您指向的文章,并且可以将 ControlTemplate 设置为基于该文章的控件的内容,这似乎很奇怪。另外,您说得很清楚,这可能不是最佳解决方案。
        • @jpierson 文章很好,但解决方案确实不是最优的。为此,我投票了+1;毕竟这是一个不同的解决方案,但它确实有效。
        猜你喜欢
        • 2023-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-07
        • 2016-09-11
        • 2020-07-10
        • 2015-01-25
        • 2016-06-10
        相关资源
        最近更新 更多