使用控制样式,如何根据toggleButton.ischecked绑定或触发更改对工具提示内容的更改?

发布于 2025-01-18 06:10:44 字数 4359 浏览 2 评论 0 原文

我定义了一个共享的 ToggleButton 样式,当 IsCheckedtrue 时显示一张图像,当 IsChecked 时显示不同的图像是。将 IsChecked 绑定到 ViewModel 上的布尔属性可以很好地显示所需的图像,因此我知道我的样式正在应用,并且 DataTrigger 绑定到 IsChecked< /代码> 有效。

我想在 IsChecked 更改时更改 ToolTip 文本,但我在实现该操作时遇到了相当多的麻烦。理想情况下,我希望 ToolTip 在未选中时显示“打开”,在选中时显示“关闭”之类的内容。

问题是 ToolTip 未连接到可视化树中的 ToggleButton,因此我需要另一种方法来查找 ToggleButton.IsChecked。我试图完全以一种风格来完成此操作,因为我有很多这样的按钮分散在各处,因此不允许对虚拟机进行任何更改。

理想情况下,该解决方案允许我使用 ToggleButton.Tag 来存储文本,并应用 ConverterStringFormat (或 ContentStringFormat )。我已经覆盖了 ContentTemplate 并将其替换为准系统 ContentPresenter 以摆脱典型的 ToggleButton 效果,因此可以进一步更改它如果需要的话。 (也许我已经删除了一些重要的内容?idk。)

这是我的样式,可以更改图像,但 ToolTip 永远不会改变。

<!--Toggle button where content is a switch image that's "On" when checked and "Off" when anything else-->
<Style TargetType="ToggleButton" x:Key="OnOffToggleButton" x:Shared="False">
    <!-- this worked to format the initial tooltip contents, but no way to bind.
    <Style.Resources> 
        <Style TargetType="ToolTip">
            <Setter Property="ContentStringFormat" Value="Turn on {0}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding ???}" Value="True">
                    <Setter Property="ContentStringFormat" Value="Turn off {0}"/>
                </DataTrigger> 
            </Style.Triggers>
        </Style>
    </Style.Resources> -->
    <Setter Property="Content" Value="{StaticResource ToggleOffImage}"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <ContentPresenter>
                    <ContentPresenter.ToolTip>
                        <TextBlock>
                            <TextBlock.Style>
                                <Style TargetType="TextBlock">
                                    <!-- this works -->
                                    <Setter Property="Text" Value="{Binding Tag, RelativeSource={RelativeSource Self}, StringFormat=Turn on {0}}"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsChecked}" Value="True">
                                            <!-- trigger has no effect -->
                                            <Setter Property="Text" Value="{Binding Tag, RelativeSource={RelativeSource Self}, StringFormat=Turn off {0}}"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBlock.Style>
                        </TextBlock>
                    </ContentPresenter.ToolTip>
                </ContentPresenter>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="True">
            <Setter Property="Content" Value="{StaticResource ToggleOnImage}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="ToolTip">
                <Setter.Value>
                    <!-- another thing that does not work -->
                    <TextBlock Text="{Binding Tag, RelativeSource={RelativeSource Self}, StringFormat=Turn off {0}}" />
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

按钮本身的定义类似于:

<ToggleButton Style="{StaticResource OnOffToggleButton}" 
              IsChecked="{Binding IsPoweredOn, Mode=OneWay}" 
              Command="{Binding TogglePowerCommand}" 
              Tag="Device Power"/>

I have a shared ToggleButton style defined that shows one image when IsChecked is true, and a different image when IsChecked is false. Binding IsChecked to a boolean property on the ViewModel works fine to show the desired image, so I know that my style is being applied and the DataTrigger bound to IsChecked works.

I would like to change the ToolTip text when IsChecked changes, but I'm having quite a bit of trouble getting that to work. Ideally I'd like the ToolTip to say something like "Turn On" when unchecked and "Turn Off" when checked.

The issue is that the ToolTip is not connected to the ToggleButton in the visual tree, so I need another way to find the ToggleButton.IsChecked. I'm trying to do this entirely in a style, because I've got quite a lot of these buttons scattered around, so no changes to the VMs are permitted.

Ideally the solution would allow me to use the ToggleButton.Tag to store the text, and apply a Converter and StringFormat (or ContentStringFormat). I've already overridden the ContentTemplate and replaced it with a barebones ContentPresenter to get rid of the typical ToggleButton effects, so it can be changed further if necessary. (And maybe I've removed something important for this to work? idk.)

Here is my style that works to change image, but the ToolTip never changes.

<!--Toggle button where content is a switch image that's "On" when checked and "Off" when anything else-->
<Style TargetType="ToggleButton" x:Key="OnOffToggleButton" x:Shared="False">
    <!-- this worked to format the initial tooltip contents, but no way to bind.
    <Style.Resources> 
        <Style TargetType="ToolTip">
            <Setter Property="ContentStringFormat" Value="Turn on {0}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding ???}" Value="True">
                    <Setter Property="ContentStringFormat" Value="Turn off {0}"/>
                </DataTrigger> 
            </Style.Triggers>
        </Style>
    </Style.Resources> -->
    <Setter Property="Content" Value="{StaticResource ToggleOffImage}"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <ContentPresenter>
                    <ContentPresenter.ToolTip>
                        <TextBlock>
                            <TextBlock.Style>
                                <Style TargetType="TextBlock">
                                    <!-- this works -->
                                    <Setter Property="Text" Value="{Binding Tag, RelativeSource={RelativeSource Self}, StringFormat=Turn on {0}}"/>
                                    <Style.Triggers>
                                        <DataTrigger Binding="{Binding IsChecked}" Value="True">
                                            <!-- trigger has no effect -->
                                            <Setter Property="Text" Value="{Binding Tag, RelativeSource={RelativeSource Self}, StringFormat=Turn off {0}}"/>
                                        </DataTrigger>
                                    </Style.Triggers>
                                </Style>
                            </TextBlock.Style>
                        </TextBlock>
                    </ContentPresenter.ToolTip>
                </ContentPresenter>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="True">
            <Setter Property="Content" Value="{StaticResource ToggleOnImage}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="ToolTip">
                <Setter.Value>
                    <!-- another thing that does not work -->
                    <TextBlock Text="{Binding Tag, RelativeSource={RelativeSource Self}, StringFormat=Turn off {0}}" />
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

The buttons themselves are defined similar to this:

<ToggleButton Style="{StaticResource OnOffToggleButton}" 
              IsChecked="{Binding IsPoweredOn, Mode=OneWay}" 
              Command="{Binding TogglePowerCommand}" 
              Tag="Device Power"/>

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

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

发布评论

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

评论(1

孤独患者 2025-01-25 06:10:45

StringFormat 不能与 ToolTip 一起使用,因为它可以包含 object 类型的任意内容,而不仅仅是纯文本。但是,ToolTip 公开了一个属性 ContentStringFormat

获取或设置一个复合string,它指定如何设置Content属性的格式(如果它显示为string.


由于 ToolTip 托管在单独的弹出窗口中,因此它与 ToggleButton 不是同一可视化树的一部分,但您可以使用 ToolTip 的 noreferrer">PlacementTarget

获取或设置 UIElement 相对于 ToolTip 打开时所处的位置。

<Style TargetType="ToggleButton" x:Key="OnOffToggleButton" x:Shared="False">
   <Setter Property="Content" Value="{StaticResource ToggleOffImage}"/>
   <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
   <Setter Property="ToolTip">
      <Setter.Value>
         <ToolTip Content="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"
                  ContentStringFormat="Turn on {0}">
         </ToolTip>
      </Setter.Value>
   </Setter>
   <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <ContentPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
   <Style.Triggers>
        <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="True">
            <Setter Property="Content" Value="{StaticResource ToggleOnImage}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="ToolTip">
               <Setter.Value>
                  <ToolTip Content="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"
                           ContentStringFormat="Turn off {0}">
                  </ToolTip>
               </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

转换器仍然可以像往常一样应用于 Content 绑定中。

<ToolTip Content="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}, Converter={StaticResource YourConverter}}"
         ContentStringFormat="Turn on {0}">

The StringFormat does not work with a ToolTip, as it can contain arbitrary content of type object, not just plain text. However, the ToolTip exposes a property ContentStringFormat that you can use.

Gets or sets a composite string that specifies how to format the Content property if it is displayed as a string.

Since a ToolTip is hosted in a separate popup window, it is not part of the same visual tree as the ToggleButton, but you can refer to it using the PlacementTarget of the ToolTip.

Gets or sets the UIElement relative to which the ToolTip is positioned when it opens.

<Style TargetType="ToggleButton" x:Key="OnOffToggleButton" x:Shared="False">
   <Setter Property="Content" Value="{StaticResource ToggleOffImage}"/>
   <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
   <Setter Property="ToolTip">
      <Setter.Value>
         <ToolTip Content="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"
                  ContentStringFormat="Turn on {0}">
         </ToolTip>
      </Setter.Value>
   </Setter>
   <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <ContentPresenter/>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
   <Style.Triggers>
        <DataTrigger Binding="{Binding IsChecked, RelativeSource={RelativeSource Self}}" Value="True">
            <Setter Property="Content" Value="{StaticResource ToggleOnImage}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="ToolTip">
               <Setter.Value>
                  <ToolTip Content="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"
                           ContentStringFormat="Turn off {0}">
                  </ToolTip>
               </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

A converter can still be applies in the Content binding as usual.

<ToolTip Content="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}, Converter={StaticResource YourConverter}}"
         ContentStringFormat="Turn on {0}">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文