DataGridTextColumn.IsReadOnly 似乎有问题

Posted

技术标签:

【中文标题】DataGridTextColumn.IsReadOnly 似乎有问题【英文标题】:DataGridTextColumn.IsReadOnly seems to be faulty 【发布时间】:2011-03-14 11:09:33 【问题描述】:

如果我创建到DataGridTextColumnIsReadOnly 属性的绑定,它不会实现。如果我通过标记设置它,它可以工作。

<DataGridTextColumn IsReadOnly="Binding IsReferenceInactive"/> <!-- NOP --> 

<DataGridTextColumn IsReadOnly="True"/> <!-- Works as expected, cell is r/o -->

IsReferenceInactive 属性是一个 DP 并且工作正常(出于测试目的,我将它绑定到一个复选框,它有效)

这是一个已知的限制吗?

更新

uups,除了我写的,输出窗口里还有一条信息:

System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。绑定表达式:路径=IsReferenceInactive;数据项=空;目标元素是“DataGridTextColumn”(HashCode=23836176);目标属性是“IsReadOnly”(类型“布尔”)

好像是这个:

http://connect.microsoft.com/VisualStudio/feedback/details/530280/wpf-4-vs2010-datagrid-isreadonly-does-not-work-with-binding-to-boolean-property

【问题讨论】:

【参考方案1】:

DataGridColumns 不是可视化树的一部分,也不像这样参与绑定。我解决它的方法是使用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>

还有其他解决方法,我发现它们有点太老套了,但它们确实有效;也就是说:http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx

【讨论】:

好的,最后我也评论了。我在输出窗口中看起来不够好。抱歉,我发的太快了。但我不会删除这个问题,也许它会帮助那些也很着急的人:) 没问题;当在 SO 上提出问题时,它为 Google/Bing 找到正确答案提供了更多素材。 @hansmaad 的答案(在“***.com/a/18657986/401246”)是最好的(并且应该标记为已接受)答案,因为它:a)保持原始显示/编辑格式,b)不是特定于显示和编辑子元素 c) 是最简单的!【参考方案2】:

与 codekaizen 相同,但更简单:

<DataGridTextColumn>
  <DataGridTextColumn.CellStyle>
    <Style>
      <Setter Property="UIElement.IsEnabled" Value="Binding IsEditable" />
    </Style>
  </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

【讨论】:

这是最好的(并且应该标记为已接受)答案,因为它:a)保持原始显示/编辑格式,b)不特定于显示和编辑子元素和 c) 是最简单的! UIElement.IsEnabled 也使单元格无法选择,这意味着这些列无法在键盘上导航,并且它们的值无法复制到剪贴板。【参考方案3】:

DataGridTextColumn 的绑定只对 Text 属性有效,对 DataGridTextColumn 的其他属性无效。

解决方案: DataGridTextColumn 告诉 DataGrid 为每一行和每一列创建一个 TextBlock。您可以为 TextBlock 定义样式并将 Style 与 Style.Key 链接到该列的 TextBlock (ElementStyle)。

当然,TextBlock 现在需要从数据列表中找到对象。它可以通过具有 AncestorType=DataGridRow 的 RelativeSource 绑定来做到这一点。然后 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>

很复杂吧?我建议您阅读我关于数据网格格式的详细文章: http://www.codeproject.com/Articles/683429/Guide-to-WPF-DataGrid-formatting-using-bindings?msg=5037235#xx5037235xx

祝你好运,你需要它:-)

【讨论】:

此解决方案不起作用。 TextBlock 没有 IsReadOnly 属性。 TextBox 具有该属性,但它只能与 EditingElementStyle 一起使用,这会产生视觉上不同的结果。【参考方案4】:

如果你喜欢@codekaizen 的解决方案,但看起来像是一个禁用的文本框,那么这可以解决问题:

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

【讨论】:

【参考方案5】:

我找到了这个解决方案,它允许您在未继承 DataContext 时绑定到数据: http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

添加 Thomas 编写的 BindingProxy 类并将此资源添加到您的 DataGrid

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="Binding" />
</DataGrid.Resources>

现在您可以按照您的预期通过BindingProxyData 属性绑定到您的DataContex

<DataGridTextColumn Header="Price"
                    Binding="Binding Price"
                    IsReadOnly="Binding Data.LockFields, Source=StaticResource proxy"/>

【讨论】:

【参考方案6】:

我找到了一个很好的解决方案,通过使用 MarkupExtension 将 DataGridColumns 与绑定一起使用。这种方式可以使用与转换器的绑定:https://***.com/a/27465022/9758687

【讨论】:

以上是关于DataGridTextColumn.IsReadOnly 似乎有问题的主要内容,如果未能解决你的问题,请参考以下文章