Привязка свойств столбца Xceed DataGrid к атрибуту свойства viewmodel

Я привязан к Xceed DataGridControl (Community Edition) с AutoCreatedColumns

ObservableCollection<ItemViewModel> Items

Я хотел бы отметить созданные столбцы ReadOnly собственность на основе Editable атрибут в свойстве viewmodel.

 class ItemViewModel : ViewModelBase {

     [Editable(false)] 
     public string Id { get; set; }

     string _comment;
     [Editable(true)]
     public string Comment {
         get { return _comment; }
         set {
              _comment = value;
              NotifyOfPropertyChanged(() => Comment);
         }
     // Other properties ...

 }

Это возможно? или есть другой способ, которым я мог бы подключиться к созданию столбца для проверки привязываемого свойства и программной установки ReadOnly?

1 ответ

Решение

Я думаю, что оптимальным решением будет просто подключиться к ItemsSourceChangeCompleted событие как это:

void _dataGrid_ItemsSourceChangeCompleted(object sender, EventArgs e)
{
    DataGridControl control = (DataGridControl)sender;
    Type itemType = control.ItemsSource.GetType().GenericTypeArguments[0];
    foreach (var col in control.Columns)
    {
        PropertyInfo propInfo = itemType.GetProperty(col.FieldName);
        if (propInfo != null)
        {
            EditableAttribute editableAttribute = propInfo.GetCustomAttributes().OfType<EditableAttribute>().FirstOrDefault();
            col.ReadOnly = (editableAttribute == null || !editableAttribute.Value);
        }
        else
        {
            col.ReadOnly = false;
        }
    }
}

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

Если вы знаете, какие столбцы вы хотите отобразить, вы можете упростить решение выше и связать столбец ReadOnly свойство как это:

public class EditableConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            PropertyInfo propInfo = value.GetType().GenericTypeArguments[0].GetProperty(parameter.ToString());
            if (propInfo != null)
            {
                EditableAttribute editableAttribute = propInfo.GetCustomAttributes().OfType<EditableAttribute>().FirstOrDefault();
                return (editableAttribute == null || !editableAttribute.Value);
            }
        }
        return false;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
<xcdg:DataGridControl.Columns>
    <xcdg:Column FieldName="Id" 
                 ReadOnly="{Binding RelativeSource={RelativeSource Self}, 
                    Path=DataGridControl.ItemsSource, 
                    Converter={StaticResource EditableConverter}, ConverterParameter=Id}" />
    <xcdg:Column FieldName="Comment" 
                 ReadOnly="{Binding RelativeSource={RelativeSource Self}, 
                    Path=DataGridControl.ItemsSource, 
                    Converter={StaticResource EditableConverter}, ConverterParameter=Comment}" />
</xcdg:DataGridControl.Columns>

Но тогда вы могли бы также выключить AutoCreateColumns и определить Columns Сбор самостоятельно в коде (или отключить AutoCreateItemProperties и создать свой собственный DataGridCollectionViewSource где вы устанавливаете каждый DataGridItemProperty.IsReadOnly соответственно).

Другие вопросы по тегам