Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF DataGrid列可见性问题_C#_Wpf_Xaml_Datagrid - Fatal编程技术网

C# WPF DataGrid列可见性问题

C# WPF DataGrid列可见性问题,c#,wpf,xaml,datagrid,C#,Wpf,Xaml,Datagrid,我在WPF中使用DataGrid,而我在列可见性方面遇到了问题。我已将ItemSource分配给ObservableCollection,并在XAML中正确设置了所有绑定,一切正常。为了方便用户,我需要能够在UI上显示和隐藏列。我已经为C#文件中的列可见性设置了绑定,这些绑定可以正常显示和隐藏大多数列。但是,包含组合框的DataGridTemplateColumns重新显示为空。绑定仍然是正确设置的,因为一旦数据更改,它就会正确地推送到UI,并且再次可见。我还验证了当列被设置为隐藏时,底层数据没

我在WPF中使用DataGrid,而我在列可见性方面遇到了问题。我已将ItemSource分配给ObservableCollection,并在XAML中正确设置了所有绑定,一切正常。为了方便用户,我需要能够在UI上显示和隐藏列。我已经为C#文件中的列可见性设置了绑定,这些绑定可以正常显示和隐藏大多数列。但是,包含组合框的DataGridTemplateColumns重新显示为空。绑定仍然是正确设置的,因为一旦数据更改,它就会正确地推送到UI,并且再次可见。我还验证了当列被设置为隐藏时,底层数据没有被清除

这是我隐藏并显示带有组合框的列时得到的结果:

完整示例代码如下所示:

XAML:


C#:

使用系统;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Linq;
使用System.Runtime.CompilerServices;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
名称空间测试
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
ObservableCollection MyDevices=新的ObservableCollection();
GlobalVars GV=新的GlobalVars();
公共主窗口()
{
初始化组件();
DeviceDataGrid.ItemsSource=MyDevices;
添加(新的ExtendedDevice(){ModelName=“Model A”,IgmpVersion=eExtendedIgmpVersion.V2});
添加(新的ExtendedDevice(){ModelName=“Model B”,IgmpVersion=eExtendedIgmpVersion.V3});
添加(新的ExtendedDevice(){ModelName=“Model C”,IgmpVersion=eExtendedIgmpVersion.Unknown});
BindingOperations.SetBinding(this.DeviceDataGrid.Columns[0],DataGridColumn.VisibilityProperty,BindingHelper.CreateOneWayBindingWithConverter(GV,“ShowColumnModelName”,new BooleanToVisibleConverter(),null));
BindingOperations.SetBinding(this.MenuViewModelName、MenuItem.IsCheckedProperty、BindingHelper.CreateTwoWayBinding(GV,“ShowColumnModelName”);
BindingOperations.SetBinding(this.DeviceDataGrid.Columns[1],DataGridColumn.VisibilityProperty,BindingHelper.CreateOneWayBindingWithConverter(GV,“ShowColumnIgmp”,new BooleanToVisibleConverter(),null));
BindingOperations.SetBinding(this.MenuViewIgmp,MenuItem.IsCheckedProperty,BindingHelper.CreateTwoWayBinding(GV,“ShowColumnIgmp”);
}
}
公共枚举EExtendedImpVersion:int
{
V3=3,
V2=2,
未知=-1,
}
公共类扩展设备:发现的设备
{
私有eExtendedIgmpVersion _IgmpVersion=eExtendedIgmpVersion.Unknown;
公共eExtendedIgmpVersion IgmpVersion
{
获取{return\u IgmpVersion;}
设置{u IgmpVersion=value;RaisePropertyChanged();}
}
公共IEnumerable IGMPVersionValue
{
得到
{
返回Enum.GetValues(typeof(eExtendedIgmpVersion)).Cast();
}
}
公共扩展设备():基(){}
}
发现的公共类设备:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私有字符串_ModelName;
公共字符串模型名
{
获取{return\u ModelName;}
设置{u ModelName=value;RaisePropertyChanged();}
}
受保护的虚拟void RaisePropertyChanged([CallerMemberName]字符串PropertyName=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(PropertyName));
}
公共发现设备()
{
}
}
静态类BindingHelper
{
公共静态绑定CreateTowayBinding(对象源,字符串路径)
{
Binding myBinding=新绑定();
myBinding.Source=Source;
myBinding.Path=新属性路径(Path);
myBinding.Mode=BindingMode.TwoWay;
myBinding.UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged;
返回myBinding;
} 
公共静态绑定CreateOneWayBindingWithConverter(对象源、字符串路径、IValueConverter转换器、对象转换器参数)
{
Binding myBinding=新绑定();
myBinding.Source=Source;
myBinding.Path=新属性路径(Path);
myBinding.Mode=BindingMode.OneWay;
myBinding.UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged;
myBinding.Converter=转换器;
myBinding.ConverterParameter=ConverterParameter;
返回myBinding;
}
}
公共类GlobalVars:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
private bool\u ShowColumnModelName=true;
公共布尔ShowColumnModelName
{
获取{return\u ShowColumnModelName;}
设置{u ShowColumnModelName=value;RaisePropertyChanged();}
}        
private bool\u ShowColumnIgmp=true;
公共图书馆
{
获取{return\u ShowColumnIgmp;}
设置{u ShowColumnIgmp=value;RaisePropertyChanged();}
}        
受保护的虚拟void RaisePropertyChanged([CallerMemberName]字符串PropertyName=null)
{
<Window x:Class="Test.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Test"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <DataGrid x:Name="DeviceDataGrid" Margin="10,50,10,10" AutoGenerateColumns="False" CanUserReorderColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Model Name" IsReadOnly="true" Binding="{Binding ModelName}" Width="Auto">
                <DataGridTextColumn.ElementStyle>
                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="VerticalAlignment" Value="Center"/>
                        <Setter Property="Margin" Value="5,0"/>
                    </Style>
                </DataGridTextColumn.ElementStyle>
            </DataGridTextColumn>
            <DataGridTemplateColumn Header="IGMP" IsReadOnly="False" Width="Auto" SortMemberPath="IgmpVersion">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Margin="4" IsEnabled="True" ItemsSource="{Binding IgmpVersionValues}" SelectedItem="{Binding IgmpVersion}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
    <Menu Height="25" VerticalAlignment="Top">
        <MenuItem Header="View" Height="25">
            <MenuItem x:Name="MenuViewModelName" Header="Model Name" HorizontalAlignment="Left" Width="175" IsCheckable="True" StaysOpenOnClick="True"/>
            <MenuItem x:Name="MenuViewIgmp" Header="IGMP" HorizontalAlignment="Left" Width="175" IsCheckable="True" StaysOpenOnClick="True"/>
        </MenuItem>
    </Menu>

</Grid>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace Test
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        ObservableCollection<ExtendedDevice> MyDevices = new ObservableCollection<ExtendedDevice>();
        GlobalVars GV = new GlobalVars();

        public MainWindow()
        {
            InitializeComponent();

            DeviceDataGrid.ItemsSource = MyDevices;

            MyDevices.Add(new ExtendedDevice() { ModelName = "Model A", IgmpVersion = eExtendedIgmpVersion.V2 });
            MyDevices.Add(new ExtendedDevice() { ModelName = "Model B", IgmpVersion = eExtendedIgmpVersion.V3 });
            MyDevices.Add(new ExtendedDevice() { ModelName = "Model C", IgmpVersion = eExtendedIgmpVersion.Unknown });

            BindingOperations.SetBinding(this.DeviceDataGrid.Columns[0], DataGridColumn.VisibilityProperty, BindingHelper.CreateOneWayBindingWithConverter(GV, "ShowColumnModelName", new BooleanToVisibleConverter(), null));
            BindingOperations.SetBinding(this.MenuViewModelName, MenuItem.IsCheckedProperty, BindingHelper.CreateTwoWayBinding(GV, "ShowColumnModelName"));

            BindingOperations.SetBinding(this.DeviceDataGrid.Columns[1], DataGridColumn.VisibilityProperty, BindingHelper.CreateOneWayBindingWithConverter(GV, "ShowColumnIgmp", new BooleanToVisibleConverter(), null));
            BindingOperations.SetBinding(this.MenuViewIgmp, MenuItem.IsCheckedProperty, BindingHelper.CreateTwoWayBinding(GV, "ShowColumnIgmp"));
        }
    }

    public enum eExtendedIgmpVersion : int
    {
        V3 = 3,
        V2 = 2,
        Unknown = -1,
    }

    public class ExtendedDevice : DiscoveredDevice
    {
        private eExtendedIgmpVersion _IgmpVersion = eExtendedIgmpVersion.Unknown;
        public eExtendedIgmpVersion IgmpVersion
        {
            get { return _IgmpVersion; }
            set { _IgmpVersion = value; RaisePropertyChanged(); }
        }
        public IEnumerable<eExtendedIgmpVersion> IgmpVersionValues
        {
            get
            {
                return Enum.GetValues(typeof(eExtendedIgmpVersion)).Cast<eExtendedIgmpVersion>();
            }
        }

        public ExtendedDevice() : base() { }
    }

    public class DiscoveredDevice : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _ModelName;
        public string ModelName
        {
            get { return _ModelName; }
            set { _ModelName = value; RaisePropertyChanged(); }
        }

        protected virtual void RaisePropertyChanged([CallerMemberName] string PropertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
        }

        public DiscoveredDevice()
        {
        }
    }

    static class BindingHelper
    {
        public static Binding CreateTwoWayBinding(Object Source, String Path)
        {
            Binding myBinding = new Binding();
            myBinding.Source = Source;
            myBinding.Path = new PropertyPath(Path);
            myBinding.Mode = BindingMode.TwoWay;
            myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;

            return myBinding;
        } 

        public static Binding CreateOneWayBindingWithConverter(Object Source, String Path, IValueConverter Converter, Object ConverterParameter)
        {
            Binding myBinding = new Binding();
            myBinding.Source = Source;
            myBinding.Path = new PropertyPath(Path);
            myBinding.Mode = BindingMode.OneWay;
            myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            myBinding.Converter = Converter;
            myBinding.ConverterParameter = ConverterParameter;

            return myBinding;
        }
    }

    public class GlobalVars : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;        

        private bool _ShowColumnModelName = true;
        public bool ShowColumnModelName
        {
            get { return _ShowColumnModelName; }
            set { _ShowColumnModelName = value; RaisePropertyChanged(); }
        }        

        private bool _ShowColumnIgmp = true;
        public bool ShowColumnIgmp
        {
            get { return _ShowColumnIgmp; }
            set { _ShowColumnIgmp = value; RaisePropertyChanged(); }
        }        

        protected virtual void RaisePropertyChanged([CallerMemberName] string PropertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
        }
    }

    public class BooleanToVisibleConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            bool? input = value as bool?;
            return input == true ? Visibility.Visible : Visibility.Hidden;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}