Условное редактирование ячеек в xamDataGrid

Я использую xamDataGrid. Я хочу отключить ячейку для столбца STATUS, если значение равно DBNull. Кажется, проблема связана с FieldSettings, я не могу передать правильное значение для этой ячейки в конвертер. Вот код:

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>

Редактировать :

Ошибка именно в этой строке:

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

Модель представления:

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");

    }
}

Конвертер:

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: мне нужно чистое решение ViewModel.


person Maverick    schedule 07.04.2014    source источник
comment
Не могли бы вы дать нам, какая информация на самом деле передается? И попробуйте это с вашей привязкой {Binding ..., TargetNullValue="Target Null"} или {Binding ..., FallbackValue="Binding Failed"}. Подробнее здесь и здесь соответственно. ХТН   -  person XAMlMAX    schedule 15.04.2014
comment
Я пытаюсь передать значение для конкретной ячейки (значение, присвоенное ей из DataTable в ViewModel). Например, Ячейка Status в пользовательском интерфейсе должна быть отключена в строке 2, поскольку она имеет значение DbNull, однако StatusNew по-прежнему будет включена, поскольку она равна нулю.   -  person Maverick    schedule 15.04.2014
comment
Вы пытались изменить путь в привязке на «СТАТУС» вместо «я»?   -  person dnr3    schedule 16.04.2014
comment
Да, это не дает мне нужного значения.   -  person Maverick    schedule 16.04.2014


Ответы (2)


Прежде всего, привязка AllowEdit не будет работать, поскольку она применяется ко всем ячейкам столбца. Вам нужен более локальный подход.

Кроме того, ваша привязка неверна. Это должно читаться примерно так:

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

На Infragistics есть сообщение, в котором кто-то пытается добиться чего-то подобного. По сути, вам нужно установить собственный шаблон управления для CellValuePresenter и добавить триггер:

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

Кроме того, создайте производные от XamDataGrid и добавьте эту часть функций, чтобы гарантировать, что IsReadOnly работает должным образом:

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

При настройке пользовательского шаблона элемента управления для CellValuePresenter вам необходимо включить реализацию по умолчанию, которую вы можете найти в %Program files%\Infragistics\NetAdvantage {version}\WPF\DefaultStyles\DataPresenter\DataPresenterGeneric_Express.xaml по адресу <Style TargetType="{x:Type igDP:CellValuePresenter}">.

person floele    schedule 22.04.2014
comment
Спасибо за ответ. Связывание, похоже, не работает. Конвертер не вызывается, если я не укажу исходное значение. - person Maverick; 22.04.2014
comment
@Maverick: Каково исходное значение? - person floele; 22.04.2014
comment
Прямо сейчас я использую Source={RelativeSource Self}. Я уверен, что это неправильно. Но тем не менее, если я не передам никакого значения для Source, отладчик не попадет в конвертер. - person Maverick; 22.04.2014
comment
@Maverick Вы разместили привязку внутри ControlTemplate или все еще используете FieldSettings? Последний все равно работать не будет, как бы вы не настроили свою привязку. - person floele; 22.04.2014

Текущий код не работает из-за ограничения WPF, поскольку AllowEdit не является элементом фреймворка, вы не можете его связать. Контекст данных доступен только для визуального дерева. Взгляните на этот форум, где они обсуждают эту проблему и предлагают альтернативные решения для обхода http://www.infragistics.com/community/forums/t/10907.aspx.

person Martijn van Put    schedule 21.04.2014