更改DataGrid列可见性(WPF,MVVM)

发布于 2025-01-23 16:28:06 字数 1937 浏览 2 评论 0原文

我最近才开始学习MVVM。我希望解决这个问题的解决方案。

在我的应用程序中,用户被授权在系统中,然后打开带有表格的窗口。用户分为角色:管理员和员工。我希望员工无法看到某个列(ID)。

我有一个授权类,其中iDroleauthorization变量存储授权用户的角色ID。我现在如何使用此值隐藏列ID?在我的情况下,如果iDroleauthorization = 2

使用freezable class找到解决方案,并在XAML中创建FrameworkElement,但我不知道找出如何解决我的问题。

methods/pretarizationmeth.cs

public class AuthorizationMeth
    {
        public static int IDRoleAuthorization;
        public bool Enter(string login, string password)
        {
            Intis6Context db = new Intis6Context();
            if (login == "" || password == "")
            {
                MessageBox.Show("You have not completed all fields", "Authorization", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
            var auth_check = db.Users.AsNoTracking().FirstOrDefault(ch => ch.Login == login && ch.Password == password);
            if (auth_check == null)
            {
                MessageBox.Show("Login or password entered incorrectly", "Authorization", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
            IDRoleAuthorization = auth_check.IdRole;
            return true;
        }
    }

view/contractview.xaml

        <DataGrid Background="White" AutoGenerateColumns="False" EnableColumnVirtualization="True" EnableRowVirtualization="True" 
                        ItemsSource="{Binding AllContrsupl_saleDTO, IsAsync=True}"
                        Grid.Row="0">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding Path=Cnssid}"/>
                <DataGridTextColumn Header="Author" Binding="{Binding Path=FULLNAMEstaff}"/>
                <DataGridTextColumn Header="Type" Binding="{Binding Path=typeTable}"/>

I just recently started learning MVVM. I hope that a solution to this problem will come.

In my application, the user is authorized in the system, after which a window with a table opens. Users are divided into roles: Administrator and Employee. I want the Employee to be unable to see a certain column (ID).

I have an AuthorizationMeth class, where the IDRoleAuthorization variable stores role ID of the authorized user. How can I now use this value to hide the column ID? In my case if IDRoleAuthorization = 2 to hide column ID

Found solutions using the Freezable class and creating a FrameworkElement in XAML but I can't figure out how this is solved for my problem.

Methods/AuthorizationMeth.cs

public class AuthorizationMeth
    {
        public static int IDRoleAuthorization;
        public bool Enter(string login, string password)
        {
            Intis6Context db = new Intis6Context();
            if (login == "" || password == "")
            {
                MessageBox.Show("You have not completed all fields", "Authorization", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
            var auth_check = db.Users.AsNoTracking().FirstOrDefault(ch => ch.Login == login && ch.Password == password);
            if (auth_check == null)
            {
                MessageBox.Show("Login or password entered incorrectly", "Authorization", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
            IDRoleAuthorization = auth_check.IdRole;
            return true;
        }
    }

View/ContractView.xaml

        <DataGrid Background="White" AutoGenerateColumns="False" EnableColumnVirtualization="True" EnableRowVirtualization="True" 
                        ItemsSource="{Binding AllContrsupl_saleDTO, IsAsync=True}"
                        Grid.Row="0">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding Path=Cnssid}"/>
                <DataGridTextColumn Header="Author" Binding="{Binding Path=FULLNAMEstaff}"/>
                <DataGridTextColumn Header="Type" Binding="{Binding Path=typeTable}"/>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寂寞陪衬 2025-01-30 16:28:06

你尝试过这样的事情吗?

如果要隐藏“ ID”列,请尝试以下操作:

您需要首先将AX:名称分配给数据杂志控件。例如“ mydatagrid”,然后您可以在后面的代码中执行此操作。

if(IDRoleAuthorization == 2)
{
    myDataGrid.Columns[0].Visibility = Visibility.Collapsed;
} 

希望这会有所帮助。

Have you tried something like this?

If you want to Hide the "ID" column try this:

You need to assign a x:Name to your DataGrid control first. For example "myDataGrid" Then you can do this in Code behind.

if(IDRoleAuthorization == 2)
{
    myDataGrid.Columns[0].Visibility = Visibility.Collapsed;
} 

Hope this helps.

白龙吟 2025-01-30 16:28:06

不要公开public static int indroleauthorization字段。这样的字段必须是属性(永远不要定义公共字段),至少是只读的属性,并且最多可以是只读实例属性(非静态)。此外,不要公开数字值,而是bool属性,例如iSauthorized。确定数字代码是否对授权用户进行评估的逻辑必须封装并且不扩散在整个应用程序中。外部类必须仅取决于此评估的结果。

datagridcolumn定义不是视觉树的一部分。他们没有渲染。他们只是包含有关列信息的占位符,稍后将由datagrid生成。实际列由datagridcolumnheaderdatagridcell elements组成。

因此,您无法在datagridcolumn.visbility属性上配置绑定

现在,您可以简单地切换单元格及其关联的标头(不会删除列,而是标题和单元格的值):

<!-- ToggleButton to simulate the IsAuthorized property -->
<ToggleButton x:Name="ToggleButton" Content="Hide/show column content" />
<DataGrid>
  <DataGrid.Columns>
      <DataGridTextColumn Header="Dynamic Column">
        <DataGridTextColumn.CellStyle>
          <Style TargetType="DataGridCell">
            <Style.Triggers>
              <DataTrigger Binding="{Binding ElementName=ToggleButton, Path=IsChecked}" Value="True">
                <Setter Property="Visibility" Value="Collapsed" />
              </DataTrigger>
            </Style.Triggers>
          </Style>
        </DataGridTextColumn.CellStyle>

        <DataGridTextColumn.HeaderStyle>
          <Style TargetType="DataGridColumnHeader">
            <Style.Triggers>
              <DataTrigger Binding="{Binding ElementName=ToggleButton, Path=IsChecked}" Value="True">
                <Setter Property="Visibility" Value="Collapsed" />
              </DataTrigger>
            </Style.Triggers>
          </Style>
        </DataGridTextColumn.HeaderStyle>
      </DataGridTextColumn>
    <DataGridTextColumn Header="Static Column" />
  </DataGrid.Columns>
</DataGrid>

要在场景中完全删除列(无自动生成的列),必须手动将其删除从datagrid.columns收集或切换列定义visibilty显式(通过访问datagrid.columns)。

将事件添加和授权变化为您的视图模型类,并让视图收听。如果处理程序设置列可见性或删除/添加列。
或者,写一个简单的附件行为:

datagridhelper.cs

class DataGridHelper : DependencyObject
{
  public static string GetHidableColumnIndices(DependencyObject attachingElement) => (string)attachingElement.GetValue(HidableColumnIndicesProperty);
  public static void SetHidableColumnIndices(DependencyObject attachingElement, string value) => attachingElement.SetValue(HidableColumnIndicesProperty, value);

  public static readonly DependencyProperty HidableColumnIndicesProperty = DependencyProperty.RegisterAttached(
      "HidableColumnIndices",
      typeof(string),
      typeof(DataGridHelper),
      new PropertyMetadata(default(string), OnHidableColumnIndicesChanged));

  public static Visibility GetColumnVisibility(DependencyObject attachingElement) => (Visibility)attachingElement.GetValue(ColumnVisibilityProperty);
  public static void SetColumnVisibility(DependencyObject attachingElement, Visibility value) => attachingElement.SetValue(ColumnVisibilityProperty, value);

  public static readonly DependencyProperty ColumnVisibilityProperty = DependencyProperty.RegisterAttached(
    "ColumnVisibility", 
    typeof(Visibility), 
    typeof(DataGridHelper), 
    new PropertyMetadata(default(Visibility), OnColumnVisibilityChanged));

  private static void OnColumnVisibilityChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
  {
    if (attachingElement is not DataGrid dataGrid)
    {
      throw new ArgumentException("Attaching element must be of type DataGrid.");
    }
    ToggleColumnVisibility(dataGrid);
  }

  private static void OnHidableColumnIndicesChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
  {
    if (attachingElement is not DataGrid dataGrid)
    {
      throw new ArgumentException("Attaching element must be of type DataGrid.");
    }
    ToggleColumnVisibility(dataGrid);
  }

  private static void ToggleColumnVisibility(DataGrid dataGrid)
  {
    IEnumerable<int> columnIndices = GetHidableColumnIndices(dataGrid)
      .Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries)
      .Select(numericChar => int.Parse(numericChar));
    foreach (int columnIndex in columnIndices)
    {
      dataGrid.Columns[columnIndex].Visibility = GetColumnVisibility(dataGrid);
    }
  }
}

用法示例

<DataGrid DatGridHelper.HidableColumnIndices="0,3,8"
          DataGridHelper.ColumnVisiblility="{Binding IsAuthenticated, Converter={StaticResource BooleanToVisibilityConverter}}" />

Don't expose a public static int IDRoleAuthorization field. Such a field must be a property (never define public fields) and at least read-only, and a read-only instance property (non-static) at best. Additionally, don't expose the numeric value, but a bool property e.g., IsAuthorized. The logic to determine whether the numeric code evaluates to an authorized user must be encapsulated and not spread across the application. External classes must depend on the result of this evaluation only.

The DataGridColumn definitions are not part of the visual tree. They are not rendered. they are just placeholders that contain information about the column, which will be generated by the DataGrid later. The actual column consists of a DataGridColumnHeader and DataGridCell elements.

Because of this, you can't configure a Binding on the DataGridColumn.Visbility property.

You can now simply toggle the cells and their associated header (which will not remove the column, but the values of the header and cells):

<!-- ToggleButton to simulate the IsAuthorized property -->
<ToggleButton x:Name="ToggleButton" Content="Hide/show column content" />
<DataGrid>
  <DataGrid.Columns>
      <DataGridTextColumn Header="Dynamic Column">
        <DataGridTextColumn.CellStyle>
          <Style TargetType="DataGridCell">
            <Style.Triggers>
              <DataTrigger Binding="{Binding ElementName=ToggleButton, Path=IsChecked}" Value="True">
                <Setter Property="Visibility" Value="Collapsed" />
              </DataTrigger>
            </Style.Triggers>
          </Style>
        </DataGridTextColumn.CellStyle>

        <DataGridTextColumn.HeaderStyle>
          <Style TargetType="DataGridColumnHeader">
            <Style.Triggers>
              <DataTrigger Binding="{Binding ElementName=ToggleButton, Path=IsChecked}" Value="True">
                <Setter Property="Visibility" Value="Collapsed" />
              </DataTrigger>
            </Style.Triggers>
          </Style>
        </DataGridTextColumn.HeaderStyle>
      </DataGridTextColumn>
    <DataGridTextColumn Header="Static Column" />
  </DataGrid.Columns>
</DataGrid>

To remove the column completely in your scenario (no auto-generated columns), you must remove it manually from the DataGrid.Columns collection or toggle the column definitions Visibilty explicitly (by accessing the DataGrid.Columns).

Add and AuthorizationChanged event to your view model class and make the view listen to it. In the event handler set the columns visibility or remove/add the column.
Alternatively, write a simple attached behavior:

DataGridHelper.cs

class DataGridHelper : DependencyObject
{
  public static string GetHidableColumnIndices(DependencyObject attachingElement) => (string)attachingElement.GetValue(HidableColumnIndicesProperty);
  public static void SetHidableColumnIndices(DependencyObject attachingElement, string value) => attachingElement.SetValue(HidableColumnIndicesProperty, value);

  public static readonly DependencyProperty HidableColumnIndicesProperty = DependencyProperty.RegisterAttached(
      "HidableColumnIndices",
      typeof(string),
      typeof(DataGridHelper),
      new PropertyMetadata(default(string), OnHidableColumnIndicesChanged));

  public static Visibility GetColumnVisibility(DependencyObject attachingElement) => (Visibility)attachingElement.GetValue(ColumnVisibilityProperty);
  public static void SetColumnVisibility(DependencyObject attachingElement, Visibility value) => attachingElement.SetValue(ColumnVisibilityProperty, value);

  public static readonly DependencyProperty ColumnVisibilityProperty = DependencyProperty.RegisterAttached(
    "ColumnVisibility", 
    typeof(Visibility), 
    typeof(DataGridHelper), 
    new PropertyMetadata(default(Visibility), OnColumnVisibilityChanged));

  private static void OnColumnVisibilityChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
  {
    if (attachingElement is not DataGrid dataGrid)
    {
      throw new ArgumentException("Attaching element must be of type DataGrid.");
    }
    ToggleColumnVisibility(dataGrid);
  }

  private static void OnHidableColumnIndicesChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
  {
    if (attachingElement is not DataGrid dataGrid)
    {
      throw new ArgumentException("Attaching element must be of type DataGrid.");
    }
    ToggleColumnVisibility(dataGrid);
  }

  private static void ToggleColumnVisibility(DataGrid dataGrid)
  {
    IEnumerable<int> columnIndices = GetHidableColumnIndices(dataGrid)
      .Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries)
      .Select(numericChar => int.Parse(numericChar));
    foreach (int columnIndex in columnIndices)
    {
      dataGrid.Columns[columnIndex].Visibility = GetColumnVisibility(dataGrid);
    }
  }
}

Usage example

<DataGrid DatGridHelper.HidableColumnIndices="0,3,8"
          DataGridHelper.ColumnVisiblility="{Binding IsAuthenticated, Converter={StaticResource BooleanToVisibilityConverter}}" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文