【问题标题】:Clicking on WPF ToggleButton changes other ToggleButtons values单击 WPF ToggleButton 会更改其他 ToggleButtons 值
【发布时间】:2016-08-18 02:50:51
【问题描述】:

我有一个带有样式触发器的简单 ToggleButton,可以根据 IsChecked 的状态更改按钮的图像。这对于一个按钮来说工作正常。但是,当我向网格添加多个按钮时,单击其中一个 ToggleButtons 会更改其他按钮的状态。我应该使用其他触发器类型而不是基于按钮样式的触发器类型吗?

这是布置三个 ToggleButtons 的 xaml 块:

   <Grid Height="362" Width="259">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <ToggleButton Style="{StaticResource TogglebuttonStyle}" IsChecked="{x:Null}" IsThreeState="True"
              Width="15" Height="15" Grid.Row="0" Grid.Column="0"/>
        <ToggleButton Style="{StaticResource TogglebuttonStyle}" IsChecked="{x:Null}" IsThreeState="True"
              Width="15" Height="15" Grid.Row="1" Grid.Column="0"/>
        <ToggleButton Style="{StaticResource TogglebuttonStyle}" IsChecked="{x:Null}" IsThreeState="True"
              Width="15" Height="15" Grid.Row="2" Grid.Column="0"/>
    </Grid>

下面是带触发器的样式:

   <Style x:Key="TogglebuttonStyle" TargetType="ToggleButton">
        <Style.Triggers>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="Content">
                    <Setter.Value>
                        <Image Source="{StaticResource ImagePlus}"/>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="IsChecked" Value="False">
                <Setter Property="Content">
                    <Setter.Value>
                        <Image Source="{StaticResource ImageMinus}"/>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="IsChecked" Value="{x:Null}">
                <Setter Property="Content">
                    <Setter.Value>
                        <Image Source="{StaticResource ImageNeutral}"/>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

我称之为解决方法,但现在每个按钮都保留了自己的状态:

我发现如果我将我的 Style 块移出 App.xaml(在标签内)并为每个按钮定义了样式触发器,问题行为就会消失。由于我对 WPF/XAML 相当陌生,我不确定它是实际解决方案还是 hacky 解决方法。以这种方式指定事物似乎是多余的。

<ToggleButton IsChecked="True" IsThreeState="True"
          Width="25" Height="25" Grid.Row="2" Margin="-1,19,1,-19">
    <ToggleButton.Style>
        <Style TargetType="ToggleButton">
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter Property="Content">
                        <Setter.Value>
                            <Image Source="{StaticResource ImagePlus}"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <Trigger Property="IsChecked" Value="False">
                    <Setter Property="Content">
                        <Setter.Value>
                            <Image Source="{StaticResource ImageMinus}"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
                <Trigger Property="IsChecked" Value="{x:Null}">
                    <Setter Property="Content">
                        <Setter.Value>
                            <Image Source="{StaticResource ImageNeutral}"/>
                        </Setter.Value>
                    </Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ToggleButton.Style>
</ToggleButton>

【问题讨论】:

  • 我尝试了您发布的示例代码,它按预期工作。每个按钮单独更改。
  • 仍然没有解决问题,但作为一个小数据点,我将切换按钮的内容更改为纯文本(“on”、“off”、“n/a”)。所有三个按钮都独立工作并保持自己的状态。

标签: c# wpf


【解决方案1】:

在做了更多研究后,我发现我必须指定不共享样式。

<Style x:Key="ToggleButtonStyle" x:Shared="False" /Style>

【讨论】:

    【解决方案2】:

    问题是setter实例化了Image控件的一个实例,它只能有一个父控件。当按钮进入“ImagePlus”状态时,一切正常。当第二个按钮进入该状态时,Image 控件将移动到新的父级,而旧的则失去了。

    这就是 XAML 具有模板的原因之一:当模板被实例化时,可视化树的 sn-p 的新实例被实例化。 Presto,没有共享问题。

    使用某些资源,您可以在资源上设置x:Shared="False" 并解决此问题。我无法在这里找到一种方法来完成这项工作(我还没有弄清楚究竟什么时候有效,什么时候无效)。所以我用 DataTemplates 代替:

    <Style x:Key="TogglebuttonStyle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
        <Style.Triggers>
            <Trigger Property="IsChecked" Value="True">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Image Source="{StaticResource ImagePlus}" />
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="IsChecked" Value="False">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Image Source="{StaticResource ImageMinus}" />
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
            <Trigger Property="IsChecked" Value="{x:Null}">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Image Source="{StaticResource ImageNeutral}" />
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
    

    【讨论】:

    • 感谢您的帮助和解释!
    猜你喜欢
    • 1970-01-01
    • 2018-04-15
    • 2019-07-30
    • 1970-01-01
    • 2011-04-27
    • 2015-12-18
    • 2021-10-10
    • 1970-01-01
    • 2014-03-15
    相关资源
    最近更新 更多