.Net v4 DataGridTextColumn.IsReadOnly кажется ошибочным
Если я создаю привязку к свойству IsReadOnly
объекта DataGridTextColumn
, он не актуализируется. Если я установил его с помощью разметки, он будет работать.
<DataGridTextColumn IsReadOnly="{Binding IsReferenceInactive}"/> <!-- NOP -->
<DataGridTextColumn IsReadOnly="True"/> <!-- Works as expected, cell is r/o -->
Свойство IsReferenceInactive
является DP и отлично работает (для целей тестирования я привязал его к флажку, который работал)
Является ли это известным ограничением?
Обновление
Uups, кроме того, что я написал, в окне вывода есть сообщение:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IsReferenceInactive; DataItem=null; target element is 'DataGridTextColumn' (HashCode=23836176); target property is 'IsReadOnly' (type 'Boolean')
Кажется, это одно:
http://connect.microsoft.com/VisualStudio/feedback/details/530280/wpf-4-vs2010-datagrid-isreadonly-does-not-work-with-binding-to-boolean-property
Ответы
Ответ 1
DataGridColumn
не являются частью визуального дерева и не участвуют в такой привязке. Способ, которым я обхожусь, это использовать DataGridTemplateColumn
.
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=myProperty}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox IsEnabled="{Binding Path=myBool}" Text="{Binding Path=myProperty Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
Существуют и другие способы обхода, которые я считаю слишком хакерскими, но они работают; wit: http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx
Ответ 2
То же, что и codekaizen, но проще:
<DataGridTextColumn>
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="UIElement.IsEnabled" Value="{Binding IsEditable}" />
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
Ответ 3
Я нашел это решение, которое позволяет связывать данные, когда DataContext не наследуется:
http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/
Добавьте класс BindingProxy
, который написал Thomas, и добавьте этот ресурс в свой DataGrid
:
<DataGrid.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>
Теперь вы можете привязать к DataContex
с помощью свойства Data
BindingProxy
как и следовало ожидать.
<DataGridTextColumn Header="Price"
Binding="{Binding Price}"
IsReadOnly="{Binding Data.LockFields, Source={StaticResource proxy}}"/>
Ответ 4
Связывание DataGridTextColumn работает только для свойства Text, но не для других свойств DataGridTextColumn.
Решение:
DataGridTextColumn сообщает DataGrid создать TextBlock для каждой строки и этого столбца. Вы можете определить стиль для TextBlock и связать стиль с Style.Key с TextBlock этого столбца (ElementStyle).
Конечно, TextBlock теперь нужно найти объект из datalist. Он может сделать это с привязкой RelativeSource с AncestorType = DataGridRow. Затем DataGridRow предоставляет доступ к объекту.
Что-то вроде этого:
<Window.Resources>
<Style x:Key="IsReadOnlyStyle" TargetType="TextBlock">
<Setter Property="IsReadOnly"
Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}},
Path =Item.NoOutput/>
</Style>
</Window.Resources>
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Value" Width="*" Binding="{Binding Value}" ElementStyle="{StaticResource IsReadOnlyStyle}"/>
</DataGrid.Columns>
Сложное право? Я рекомендую вам прочитать мою подробную статью о форматировании datagrid по адресу:
http://www.codeproject.com/Articles/683429/Guide-to-WPF-DataGrid-formatting-using-bindings?msg=5037235#xx5037235xx
Удачи, вам это нужно: -)
Ответ 5
Если вам нравится решение @codekaizen, но будет выглядеть отключенным TextBox, тогда это будет делать трюк:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox IsEnabled="{Binding Path=myBool}" Text="{Binding Path=myProperty}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox IsEnabled="{Binding Path=myBool}" Text="{Binding Path=myProperty, Mode=TwoWay}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>