【问题标题】:Hide/Show DataGrid based on Selected ListBoxItem in WPF基于 WPF 中选定的 ListBoxItem 隐藏/显示 DataGrid
【发布时间】:2013-04-16 11:37:48
【问题描述】:

我有一个ListBox

<ListBox Name="ListB" SelectedIndex="0" ItemsSource="{Binding Account}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>

                <TextBlock FontSize="16" Grid.Column="0" Grid.RowSpan="3"> 
                    <TextBlock.Text>
                        <MultiBinding StringFormat="{}{0} {1}" >
                            <Binding Path="AccountNumber" />
                            <Binding Path="Name" />
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

基于AccountNumber我想Show/HideDataGrid's绑定到ListBoxItems:

<!--DataGrid 1-->       
    <DataGrid ItemsSource="{Binding ElementName=ListB, Path=SelectedItem}">
..................
</DataGrid>

 <!--DataGrid 2-->      
    <DataGrid ItemsSource="{Binding ElementName=ListB, Path=SelectedItem}">
..................
</DataGrid>

WPF 中有 if/else 吗?例如

if SelectedItem in ListBox has an AccountNumber 100 
      than show DataGrid 1 and hide DataGrid 2
else hide DataGrid 1 and show DataGrid 2.

提前感谢您的提示。

【问题讨论】:

  • 你可以为你的 List 处理 SelectionChanged 事件,然后在那里执行你的逻辑吗?
  • 是的,它在后面的代码中使用 SelectionChanged 事件。谢谢

标签: wpf datagrid listbox


【解决方案1】:

不幸的是,WPF 没有 if/then/else 结构。您必须建立一个工作区或使用框架,这可以解决您的问题。一种可能的解决方案是使用 blend sdk 的交互触发框架:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 

您提到的行为将实现如下:

<i:Interaction.Triggers>
   <!-- One Trigger for equal 100 -->
   <ei:DataTrigger Binding="{Binding Path=SelectedItem.AccountNumber,
                                     ElementName=ListB}"
                   Value="100">
      <ei:ChangePropertyAction TargetName="DataGrid1" 
                               PropertyName="Visibility" 
                               Value="Collapsed" />
      <ei:ChangePropertyAction TargetName="DataGrid2" 
                               PropertyName="Visibility" 
                               Value="Visible" />

   </ei:DataTrigger> 

   <!-- One Trigger for not equal 100 -->
   <ei:DataTrigger Binding="{Binding Path=SelectedItem.AccountNumber,
                                     ElementName=ListB}"
                   Comparison="NotEqual"
                   Value="100">
      <ei:ChangePropertyAction TargetName="DataGrid1" 
                               PropertyName="Visibility" 
                               Value="Visible" />
      <ei:ChangePropertyAction TargetName="DataGrid2" 
                               PropertyName="Visibility" 
                               Value="Collapsed" />

   </ei:DataTrigger> 

</i:Interaction.Triggers>

您需要将 System.Windows.Interactivity.dll 包含到您的项目引用中。 还需要 Microsoft.Expression.Interactions.dll

另一种解决方案是将 DataGrid 的可见性直接绑定到 SelectedItem.AccountNumber 并附加和 IValueConverter,后者根据逻辑提取可见性。

使用 ListBox 的 SelectionChanged 事件也可以,但变得非常不可读并且可能是多余的。如果你遵循 MVVM 方法,你的代码应该几乎是空的。

【讨论】:

  • 你好 JanW。我将 System.Windows.Interactivity DLL 包含到我的项目中,但出现许多错误:找不到属性,找不到操作数。后面的代码按照 PGallagher 的建议工作,但即使我对结果感到满意,我也想以正确的方式使用 MVVM 方法。
  • 嘿 Georg,对不起,我从脑海中复制了解决方案。如果您在 MSDN 上查找这些类,您会发现我打错了:属性应该是 PropertyName 而操作数应该是比较。我在回答中更正了这两个。 DataTrigger on MSDNChangePropertyAction on MSDN
【解决方案2】:

如果您使用的是 MVVM 框架,这将很简单。

将 BooleanToVisibility 转换器添加到您的视图中,如 this example 中一样,使用布尔属性来控制 ViewModel 中每个网格的可见性,只要 ListBox.SelectedItem 更改,这些网格就会更新。

【讨论】:

    猜你喜欢
    • 2011-04-24
    • 2011-07-18
    • 1970-01-01
    • 2013-08-07
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多