Maverick
Maverick

Reputation: 801

Conditional cell editing in xamDataGrid

I'm using a xamDataGrid. I want to disable the cell for STATUS column, if the value is DBNull. The issue seems to be with the FieldSettings, I'm not able to pass the correct value for that cell to the Converter. Here is the code :

XAML :

<Window.Resources>
    <dbNullConverter:DBNullToBooleanConverter x:Key="NullToBooleanConverter" />
</Window.Resources>
<Grid>
    <DockPanel>
        <IgDp:XamDataGrid x:Name="gridData" DataSource="{Binding Path=TempDataTable}">
            <IgDp:XamDataGrid.FieldLayoutSettings>
                <IgDp:FieldLayoutSettings AutoGenerateFields="True"/> 
            </IgDp:XamDataGrid.FieldLayoutSettings>

            <IgDp:XamDataGrid.FieldSettings>
                <IgDp:FieldSettings AllowEdit="True" />
            </IgDp:XamDataGrid.FieldSettings>

            <IgDp:XamDataGrid.FieldLayouts>
                <IgDp:FieldLayout>
                    <IgDp:Field Name="STATUS" Label="STATUS">
                        <IgDp:Field.Settings>
                            <IgDp:FieldSettings AllowEdit="{Binding Source={RelativeSource Self}, Path=Self, Converter={StaticResource NullToBooleanConverter}}" />
                        </IgDp:Field.Settings>
                    </IgDp:Field>
                    <IgDp:Field Name="ROWID" />
                    <IgDp:Field Name="RESULT" Label="VALUE" />
                    <IgDp:Field Name="HasRowBeenEdited" Label="Edited ?">
                        <IgDp:Field.Settings>
                            <IgDp:FieldSettings EditorType="{x:Type igEditors:XamCheckEditor}"/>
                        </IgDp:Field.Settings>
                    </IgDp:Field>
                </IgDp:FieldLayout>
            </IgDp:XamDataGrid.FieldLayouts>
        </IgDp:XamDataGrid>
    </DockPanel>
</Grid>

Edit :

The error is in this line :

<IgDp:FieldSettings AllowEdit="{Binding Source={RelativeSource Self}, Path=Self, Converter={StaticResource NullToBooleanConverter}}" />

ViewModel :

public class DBNullConverterViewModel : INotifyPropertyChanged
{
    private DataTable tempDataTable;
    public DataTable TempDataTable
    {
        get { return tempDataTable; }
        set
        {
            tempDataTable = value;
            RaisedPropertyChanged("tempDataTable");
        }
    }

    public DBNullConverterViewModel()
    {
        TempDataTable = new DataTable();
        GetValue();
    }

    private void GetValue()
    {
        tempDataTable.Columns.Add(new DataColumn("ROWID", typeof(Int32)));
        tempDataTable.Columns.Add(new DataColumn("STATUS", typeof(string)));
        tempDataTable.Columns.Add(new DataColumn("StatusNew", typeof(string)));
        tempDataTable.Columns.Add(new DataColumn("HasRowBeenEdited", typeof(bool)));

        DataRow row = tempDataTable.NewRow();
        row["ROWID"] = 1;
        row["STATUS"] = "Active";
        row["StatusNew"] = "New";
        row["HasRowBeenEdited"] = true;
        tempDataTable.Rows.Add(row);
        tempDataTable.AcceptChanges();

        DataRow row1 = tempDataTable.NewRow();
        row1["ROWID"] = 2;
        row1["STATUS"] = DBNull.Value;
        row1["StatusNew"] = null;
        row1["HasRowBeenEdited"] = DBNull.Value;
        tempDataTable.Rows.Add(row1);
        tempDataTable.AcceptChanges();

        RaisedPropertyChanged("tempDataTable");

    }
}

Converter :

public class DBNullToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == DBNull.Value)
            return false;

        return true;
    }

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

IMP : I'm looking for a pure ViewModel Solution.

Upvotes: 1

Views: 5939

Answers (2)

floele
floele

Reputation: 3788

First of all, binding AllowEdit won't work because it applies to all cells of a column. You need a more local approach.

Also, your binding is incorrect. It should read something like that:

{Binding Path=DataItem[STATUS], Converter={StaticResource NullToBooleanConverter}}

There is a post at Infragistics where someone tries to achieve something similar. In a gist, what you need to do is setting a custom control template for the CellValuePresenter and add a trigger:

<ControlTemplate.Triggers>
    <DataTrigger Binding="{Binding DataItem[STATUS], Converter={StaticResource NullToBooleanConverter}}" Value="True">
      <Setter Property="igEditors:ValueEditor.IsReadOnly" Value="false" />
    </DataTrigger>
  </ControlTemplate.Triggers>

Additionally, derive from XamDataGrid and add this piece of functionality to ensure IsReadOnly works as intended:

protected override void OnEditModeStarting(Infragistics.Windows.DataPresenter.Events.EditModeStartingEventArgs args)
{
    var cell = args.Cell;    
    var cellEditor = Infragistics.Windows.DataPresenter.CellValuePresenter.FromCell(cell).Editor;
    if (cellEditor != null && !cellEditor.IsReadOnly)
        base.OnEditModeStarting(args);
    else args.Cancel=true;
}

When setting a custom control template for CellValuePresenter, you need to need to include the default implementation you can find in %Program files%\Infragistics\NetAdvantage {version}\WPF\DefaultStyles\DataPresenter\DataPresenterGeneric_Express.xaml at <Style TargetType="{x:Type igDP:CellValuePresenter}">.

Upvotes: 2

Martijn van Put
Martijn van Put

Reputation: 3313

You're current code doesn't work due to an limitation of WPF, because the AllowEdit is not an Framework Element you cannot bind it the Data Context is only available to the visual tree. Take a look at this forum where they discuss this problem and give alternative solutions for workaround http://www.infragistics.com/community/forums/t/10907.aspx.

Upvotes: 0

Related Questions