【问题标题】:Expand/Collapse all expanders展开/折叠所有扩展器
【发布时间】:2013-07-08 22:06:52
【问题描述】:

我有一个扩展器列表,我想用全局切换按钮控制其展开状态(IsExpanded),该按钮应该在展开/折叠状态之间切换。

到目前为止,我得到的解决方案是将扩展器的 IsExpanded 状态绑定到切换按钮的 IsChecked 状态。只要我不手动不切换扩展器,这就会起作用。一旦我这样做了,那些特定的扩展器就不会尊重绑定(切换按钮的 IsChecked 状态)。

知道为什么吗? XAML 中是否有一个干净的解决方案?

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid>  
  <StackPanel>
    <ToggleButton Name="ExpandAll">Toggle</ToggleButton>  
    <Expander IsExpanded="{Binding ElementName=ExpandAll,Path=IsChecked, Mode=OneWay}">
      Hai
    </Expander>
    <Expander IsExpanded="{Binding ElementName=ExpandAll,Path=IsChecked, Mode=OneWay}">
      Hello
    </Expander>
    <Expander IsExpanded="{Binding ElementName=ExpandAll,Path=IsChecked, Mode=OneWay}">
      Weird
    </Expander>
    </StackPanel>
  </Grid>
</Page>

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    我知道这篇文章很老了。只是为遇到的其他人发布此信息。下面的代码对我有用。

    <Expander IsExpanded="{Binding ElementName=ExpandAll, Path=IsChecked, UpdateSourceTrigger=Explicit}">
    </Expander>
    

    这在动态生成扩展器时有效,例如在 DataGrid.RowDetailsTemplate 内。

    【讨论】:

      【解决方案2】:

      我认为您无法完全在 XAML 中实现这一点,但以下允许您使用 IValueConverter 来实现这一点:

      <StackPanel>
              <StackPanel.Resources>
                  <local:Converter x:Key="Converter" />
              </StackPanel.Resources>
              <ToggleButton Name="ExpandAll">
                  <ToggleButton.IsChecked>
                      <MultiBinding Mode="OneWayToSource" Converter="{StaticResource Converter}">
                          <Binding ElementName="Expander1" Path="IsExpanded" />
                          <Binding ElementName="Expander2" Path="IsExpanded" />
                          <Binding ElementName="Expander3" Path="IsExpanded" />
                      </MultiBinding>
                  </ToggleButton.IsChecked>
                  Toggle</ToggleButton>
              <Expander Name="Expander1">
                  Hai
              </Expander>
              <Expander Name="Expander2">
                  Hello
              </Expander>
              <Expander Name="Expander3">
                  Weird
              </Expander>
          </StackPanel>
      

      您的Converter 如下:

      public class Converter : IMultiValueConverter
      {
          public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
          {
              //we're using OneWayToSource, so this will never be used.
              return DependencyProperty.UnsetValue;
          }
      
          public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
          {
              // we want to convert the single 'IsChecked' value from the ToggleButton into 
              // 3 'IsExpanded' values
              var allValues = new object[targetTypes.Length];
              for (int i = 0; i < allValues.Length; i++)
              {
                  allValues[i] = value;
              }
      
              return allValues;
          }
      }
      

      这通过在ToggleButtonIsChecked 属性之间设置OneWayToSource 绑定来工作(即,当目标值更改时,绑定将针对源设置),并使用IMultiValueConverter 将单个值转换为每个 Expanders 的一个值。

      【讨论】:

      • 嗨,史蒂夫,这行得通。如果扩展器没有固定并且由 ItemsControl 生成,您知道如何修改此解决方案吗?
      • @Pradeep - 不,我认为使用这种方法是不可能的,因为MultiBinding 需要Bindings 的具体列表。如果需要,那么您可能需要考虑实现视图模型或(上帝禁止)一些代码
      • @Steve Greatrex:在我们手动展开/折叠后,OP 问题中的绑定会中断什么? WPF4 中是否有比这里更好的方法?有没有cmets?
      • 另外,UpdateSourceTrigger=ExplicitMode=TwoWay 对我有用。
      猜你喜欢
      • 1970-01-01
      • 2015-03-29
      • 2014-02-13
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 2016-04-29
      • 2021-11-10
      • 2016-05-31
      相关资源
      最近更新 更多