Reputation: 710
I'm binding to an Xceed DataGridControl (Community Edition) with AutoCreatedColumns
ObservableCollection<ItemViewModel> Items
I would like to mark the created columns' ReadOnly
property based on the Editable
attribute on the viewmodel property.
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 ...
}
Is this possible? or is there another way I could hook into the creation of the column to inspect the property that is being bound and programmatically set ReadOnly?
Upvotes: 1
Views: 4155
Reputation: 411
I think the optimal solution is to just hook up to ItemsSourceChangeCompleted
event like this:
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;
}
}
}
Alternatively, you could bind the cell ReadOnly
property to your editable attribute as described here.
If you know what columns you want to display you could simplify the solution above and bind the column ReadOnly
property like this:
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>
But then, you might as well turn off AutoCreateColumns
and define the Columns
collection by yourself in code (or turn off AutoCreateItemProperties
and create your own DataGridCollectionViewSource
where you set each DataGridItemProperty.IsReadOnly
appropriately).
Upvotes: 1