-1

I have a DataGrid like this:

    <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>

This is working right now, however, I'd like to add some functionality, namely I'd like the Student's grade column to become read only IF the grade is above 1. I keep seeing solutions like this, where people use a DataGridVIEW programatically. However, I can't seem to add a DataGridVIEW to my XAML, only a DataGrid. And when I'm trying to do something like:

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

I can't, since DataGrid doesn't have an enumerator. Nor can I access its rows with something like studentGrid.Row.

So my questions would be, what's the difference in usage of DataGrid vs DataGridView, and how can I add an if-else validation to make certain rows in a column of a DataGrid editable, but others not?

Thank you!

UPDATE

So I've created a converter, but I'm having trouble using it. I'm trying to reference it in the 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>

But I get an error:

The name "GradeToReadOnlyConverter" does not exist in the namespace "clr-namespace:TanulmanyiRendszer.Admin.ViewModel".

Even though the converter clearly exists in that namespace:

namespace TanulmanyiRendszer.Admin.ViewModel
{
    public class GradeToReadOnlyConverter : IValueConverter
    {
Community
  • 1
  • 1
lte__
  • 7,175
  • 25
  • 74
  • 131
  • you can bind IsReadOnly dp of a datagrid to a Property in ViewMdel and toggle it based on StudentGrade property using a converter. – Abhinav Sharma May 17 '17 at 07:45
  • @AbhinavSharma Thank you, I've run into another issue while adding the converter. I've updated the post. – lte__ May 17 '17 at 08:16
  • http://stackoverflow.com/questions/14665713/the-name-does-not-exist-in-the-namespace-error-in-xaml have a look – Abhinav Sharma May 17 '17 at 09:38

2 Answers2

0

You can use a converter for the same.

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();
    }

Update. After looking into This link

I have updated the the xaml as Datagrid column are not considered as a control hence you cannot assign a converter to it.I have made a small workaround that will solve your issue

<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>
Community
  • 1
  • 1
Abhinav Sharma
  • 443
  • 1
  • 4
  • 15
  • Thank you! This will work, but I have a small issue: How to add the converter class to the XAML reference? I've found a tutorial here: https://wpftutorial.net/ValueConverters.html In his example, he's using: `` `` `` But I get an error stating `The namespace prefix 'l' is not defined`. How can I reference the converter class in the XAML? – lte__ May 17 '17 at 08:05
  • @lte__ "l" is not defined because you forgot to add the place of your converter in your main xaml tag. You have to extended with "xmlns:l="clr-namespace: *HereYourConverterNameSpace* " in your window tag (or usercontrol...). You can choose better name instead of "l". It can be (For example) "converters". In this way "xmlns:converters="clr-namespace:..." – Péter Hidvégi May 17 '17 at 08:25
  • Okay, I did that now, but the converter never gets called :/ – lte__ May 17 '17 at 08:26
0

You could use an EditingElementStyle that disables the TextBox based on the value returned from your converter:

<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>
mm8
  • 163,881
  • 10
  • 57
  • 88