【问题标题】:How to hide DataGrid column in WPF automatically using MVVM? [duplicate]如何使用 MVVM 自动隐藏 WPF 中的 DataGrid 列? [复制]
【发布时间】:2014-09-06 20:34:21
【问题描述】:

使用 MVVM(无代码隐藏),我想在选择时隐藏我的 DataGrid 列,我有以下代码:

<DataGrid ItemsSource="{Binding SSID}" Grid.Row="1"  Margin="10,10,0,0" Height="200" Width="500" Grid.ColumnSpan="2" Name="dg" HorizontalAlignment="Left" AutoGenerateColumns="False">
    <DataGrid.Columns>
      <DataGridTextColumn Header="Network ID" Binding="{Binding _networkID}"></DataGridTextColumn>
      <DataGridTextColumn Header="SSID" Binding="{Binding _ssid}"></DataGridTextColumn>
      <DataGridTextColumn Header="VLAN" Binding="{Binding _vlan}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _authenticationMode}" Binding="{Binding _authenticationMode}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _authentication}" Binding="{Binding _authentication}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _staticWEPKeyType}" Binding="{Binding _staticWEPKeyType}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _staticWEPKeyLength}" Binding="{Binding _staticWEPKeyLength}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _staticWEPKey1}" Binding="{Binding _staticWEPKey1}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _staticWEPKey2}" Binding="{Binding _staticWEPKey2}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _staticWEPKey3}" Binding="{Binding _staticWEPKey3}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _staticWEPKey4}" Binding="{Binding _staticWEPKey4}"></DataGridTextColumn>
      <DataGridTextColumn Visibility="{Binding _wpaPersonalKeyAC}" Binding="{Binding _wpaPersonalKeyAC}"></DataGridTextColumn>
   </DataGrid.Columns>
</DataGrid>

C#代码是:

var ssid = new SSIDPropertyClass();

ssid._networkID = SSID.Count + 1;
ssid._ssid = EnteredSSIDAC;
ssid._vlan = VlanSSID;

if (ACSelectedSecurityType=="Static WEP")
{
    ssid._authenticationMode = ACSelectedSecurityType;
    ssid._authentication = ACStaticWEPSelectedAuthentication;

    ssid._staticWEPKeyType = ACStaticWEPSelectedKeyType;
    ssid._staticWEPKeyLength = ACStaticWEPSelectedKeyLength;

    ssid._staticWEPKey1 = StaticWEPKey1;
    ssid._staticWEPKey2 = StaticWEPKey2;
    ssid._staticWEPKey3 = StaticWEPKey3;
    ssid._staticWEPKey4 = StaticWEPKey4;

    SSID.Add(ssid);
}
else if(ACSelectedSecurityType=="WPA/WPA2 Personal")
{
    ssid._authenticationMode = ACSelectedSecurityType;
    ssid._wpaPersonalKeyAC = WpaACKey;

    SSID.Add(ssid);
}

我希望当执行 if 块时,它只在数据网格中添加块列,而对于其他 else if 块,它总是显示额外的列。例如,当执行 else if 时,它总是显示我不需要的额外列我只想显示我在 SSID 集合中添加的那两个,但它也显示是否阻止列。所以简而言之,我想让额外列的可见性为 false。谁能解决我的问题,因为我需要明天提交.任何帮助将是非常明显的?

【问题讨论】:

标签: c# wpf xaml mvvm datagrid


【解决方案1】:

如果要隐藏Column,需要像这样指定PropertyVisibility

YourDataGrid.Columns[IndexOftheColumn].Visibility = Visibility.Collapsed;

如果您想隐藏第一列,请说“网络 ID”

dg.Columns[0].Visibility = Visibility.Collapsed;

【讨论】:

  • 我没有代码隐藏选项,因为我使用的是 MVVM 模型,如您上面所说,我无法直接访问我的 dg!
  • @Sapper 您应该在问题中明确说明您正在使用 MVVM。
  • 在哪个事件中??? DataGrid 中的列在第一次出现时已经“加载”了很多。上面的代码失败,因为集合中没有列。
【解决方案2】:

对于那些希望将其隐藏在 XAML 中的人

它看起来像这样:

<DataGridTextColumn Visibility="Collapsed" Header="Merchant Reference" Binding="{Binding MerchantReference}" Width="200" />

在 XAML 中而不是在代码中执行此操作的原因之一是当您的模板具有不适用于某些情况的额外列,但您很懒惰并且不想制作单独的模板和支持类.
另一个原因只是为了测试它看起来如何隐藏。
第三个是从隐藏开始,然后通过一些触发器使其在模型中可见

【讨论】:

  • @reasra 您好 Reasra,您想详细说明您发布此链接的原因吗?谢谢。
  • 几天来我一直在与DataGridTextColumn 上的可见性作斗争,这并不像设置可见性那么简单。由于我不完全理解但在链接答案中进行了解释的原因,绑定值时该列没有“视觉连接”到数据网格。当我在寻找答案时偶然发现这篇文章时,我只是想详细说明一下,因为我想不出将可见性设置为恒定值的任何原因(尽管它可能有效)。
  • @reasra 一个例子是当你有一个模板有额外的列不适用于某些情况,但你很懒,不想制作单独的模板和支持类。或者只是为了测试它看起来如何隐藏。或者从隐藏开始,然后通过一些触发器使其在模型中可见。
【解决方案3】:

您不必隐藏列,只需将其 MaxWidth 属性设置为零即可。

        DataGrid.Columns[IndexOfColumn].MaxWidth = 0;

【讨论】:

    【解决方案4】:

    在 MVVM 中,这通常通过 ValueConverter 处理

    public sealed class BoolToVisibilityConverter : IValueConverter
    {
       public Visibility TrueValue { get; set; }
       public Visibility FalseValue { get; set; }
    
       public BoolToVisibilityConverter()
       {
          // Set defaults
          this.TrueValue = Visibility.Visible;
          this.FalseValue = Visibility.Collapsed;
       }
    
       public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
       {
           bool flag = false;
           if (value is bool)
           {
              flag = (bool)value;
           }
           else if (value is bool?)
           {
              bool? nullable = (bool?)value;
              flag = nullable.HasValue ? nullable.Value : false;
          }
          return flag ? this.TrueValue : this.FalseValue;
      }
    
      public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
      {
          if (object.Equals(value, this.TrueValue))
              return true;
          if (object.Equals(value, this.FalseValue))
            return false;
          return null;
      }
    }
    

    因为 DataGridTextColumn 或任何其他受支持的 dataGrid 列不位于 DataGrid 的可视树中(请参阅Binding Visibility for DataGridColumn in WPF),因此需要添加绑定代理

    public class BindingProxy : Freezable
    {
    #region Overrides of Freezable
    
    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }
    
    #endregion
    
    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }
    
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object),
                                     typeof(BindingProxy));
    

    }

    在资源部分添加

    <ResourceDictionary>
       <namespace:BoolToVisibilityConverter x:Key="BoolToCollapsed" TrueValue="Visible" FalseValue="Collapsed" />
       <namespace:BindingProxy x:Key="Proxy" Data="{Binding}"/>
    </ResourceDictionary>
    

    在你的数据网格上

     <DataGrid ItemsSource="{Binding Items}" >
        <DataGrid.Columns>
          <DataGridTextColumn Visibility="{Binding Data.ShowThisColumnFlag, Source={StaticResource Proxy}, Converter={StaticResource BoolToCollapsed}}" Binding="{Binding PropertyOne}" />
    
          <DataGridTextColumn Visibility="{Binding Data.ShowAnotherColumnFlag, Source={StaticResource Proxy}, Converter={StaticResource BoolToCollapsed}}" Binding="{Binding PropertyTwo}"/>
        </DataGrid.Columns>
     </DataGrid>
    

    您应该根据需要设置您的模式。

    感谢 Rohit Vats 的 BindingProxy 帖子。

    【讨论】:

    • 这会导致错误,因为 DataGridTextColumn 不在可视树中并且无权访问 DataContext。
    • 错误:“找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。”
    • 对于缺少 DataGridTextColumn 的道歉不在可视树中。已更新更正解决方案
    猜你喜欢
    • 2011-12-24
    • 2010-11-07
    • 2011-03-05
    • 2020-05-21
    • 2011-10-15
    • 2013-06-23
    • 1970-01-01
    • 2014-10-29
    • 2015-08-18
    相关资源
    最近更新 更多