【问题标题】:C#/WPF - Make DataGrid readonly with if clauseC#/WPF - 使用 if 子句使 DataGrid 只读
【发布时间】:2017-05-17 07:38:20
【问题描述】:

我有一个这样的DataGrid

    <DataGrid Name="studentGrid" Grid.Row="3" Grid.ColumnSpan="2" AutoGenerateColumns="False" ItemsSource="{Binding Students, Mode=TwoWay}" >
        <DataGrid.Columns>
            <DataGridTextColumn IsReadOnly="True" Header="Student's name" Binding="{Binding StudentName}" />
            <DataGridTextColumn IsReadOnly="True" Header="Student's username" Binding="{Binding StudentUserName}" />
            <DataGridTextColumn IsReadOnly="True" Header="Date of application" Binding="{Binding DateOfApplication}"  />
            <DataGridTextColumn IsReadOnly="False" Header="Student's grade" Binding="{Binding StudentGrade}"/>
        </DataGrid.Columns>
    </DataGrid>

这正在工作,但是,我想添加一些功能,即如果等级高于 1,我希望 Student's grade 列变为只读。我一直看到像 this 这样的解决方案,人们以编程方式使用 DataGridVIEW 的地方。但是,我似乎无法将 DataGridVIEW 添加到我的 XAML,只能添加一个 DataGrid。当我尝试做类似的事情时:

public MainWindow()
{
    foreach (var row in studentGrid)
    {
        if (row[3] > 1) {
            row[3].isReadOnly = false;
        }
    }
    InitializeComponent();
}

我不能,因为 DataGrid 没有枚举器。我也不能用studentGrid.Row之类的东西访问它的行。

所以我的问题是,DataGrid 与 DataGridView 的使用有何不同,如何添加 if-else 验证以使 DataGrid 列中的某些行可编辑,而其他行不能?

谢谢!

更新

所以我创建了一个转换器,但我在使用它时遇到了问题。我正在尝试在 XAML 中引用它:

<Window x:Class="TanulmanyiRendszer.Admin.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:system="clr-namespace:System;assembly=mscorlib" 
        xmlns:viewModel="clr-namespace:TanulmanyiRendszer.Admin.ViewModel"
        Title="Courses" Height="600" Width="500">
    <Window.Resources>
        <viewModel:GradeToReadOnlyConverter x:Key="converter" />
    </Window.Resources>

但我得到一个错误:

命名空间中不存在名称“GradeToReadOnlyConverter” “clr 命名空间:TanulmanyiRendszer.Admin.ViewModel”。

即使转换器显然存在于该命名空间中:

namespace TanulmanyiRendszer.Admin.ViewModel
{
    public class GradeToReadOnlyConverter : IValueConverter
    {

【问题讨论】:

  • 您可以将数据网格的 IsReadOnly dp 绑定到 ViewMdel 中的属性,并使用转换器根据 StudentGrade 属性进行切换。
  • @AbhinavSharma 谢谢,我在添加转换器时遇到了另一个问题。我已经更新了帖子。

标签: c# wpf datagridview datagrid


【解决方案1】:

您也可以使用转换器。

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        if (value is int) {
            var gradeVal = (int)value;
            return gradeVal > 1;
        } else
            return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }

更新。 在查看This link

我已经更新了 xaml,因为 Datagrid 列不被视为控件,因此您无法为其分配转换器。我做了一个小变通方法来解决您的问题

<DataGridTextColumn Binding="{Binding StudentGrade}">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding Path=StudentGrade,Converter={StaticResource yourConverter}}" Value="True">
                                <Setter Property="IsEnabled" Value="False"/>
                                <Setter Property="Foreground" Value="Black"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>

【讨论】:

  • 谢谢!这会起作用,但我有一个小问题:如何将转换器类添加到 XAML 引用?我在这里找到了一个教程:wpftutorial.net/ValueConverters.html 在他的示例中,他正在使用:&lt;Window.Resources&gt; &lt;l:BoolToVisibilityConverter x:Key="converter" /&gt; &lt;/Window.Resources&gt; 但我收到一条错误消息,指出 The namespace prefix 'l' is not defined。如何在 XAML 中引用转换器类?
  • @lte__ "l" 未定义,因为您忘记在主 xaml 标记中添加转换器的位置。您必须在窗口标签(或用户控件...)中使用“xmlns:l="clr-namespace: HereYourConverterNameSpace”进行扩展。您可以选择更好的名称而不是“l”。它可以是(例如)“converters”。这样“xmlns:converters="clr-namespace:..."
  • 好的,我现在这样做了,但是转换器永远不会被调用:/
【解决方案2】:

您可以使用EditingElementStyle,根据转换器返回的值禁用TextBox

<DataGrid Name="studentGrid" Grid.Row="3" Grid.ColumnSpan="2" AutoGenerateColumns="False"
                  ItemsSource="{Binding Students, Mode=TwoWay}" >
    <DataGrid.Resources>
        <Style x:Key="ReadOnlyStyle" TargetType="TextBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding StudentGrade, Converter={StaticResource converter}}" Value="True">
                    <Setter Property="BorderThickness" Value="0" />
                    <Setter Property="IsEnabled" Value="False" />
                    <Setter Property="Background" Value="Transparent" />
                    <Setter Property="TextWrapping" Value="Wrap" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn IsReadOnly="True" Header="Student's name" Binding="{Binding StudentName}" />
        <DataGridTextColumn IsReadOnly="True" Header="Student's username" Binding="{Binding StudentUserName}" />
        <DataGridTextColumn IsReadOnly="True" Header="Date of application" Binding="{Binding DateOfApplication}"  />
        <DataGridTextColumn Header="Student's grade" Binding="{Binding StudentGrade}" EditingElementStyle="{StaticResource ReadOnlyStyle}"/>
    </DataGrid.Columns>
</DataGrid>

【讨论】:

    猜你喜欢
    • 2023-03-19
    • 2011-01-30
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 2011-01-03
    • 2012-02-08
    相关资源
    最近更新 更多