Подтвердить что ты не робот

.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

4b9b3361

Ответ 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>