【问题标题】:DataGridTextColumn.IsReadOnly seems to be faultyDataGridTextColumn.IsReadOnly 似乎有问题
【发布时间】: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

【问题讨论】:

    标签: .net wpf datagrid


    【解决方案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 的答案(在“stackoverflow.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://stackoverflow.com/a/27465022/9758687

        【讨论】:

          猜你喜欢
          • 2022-06-22
          • 1970-01-01
          • 2012-09-01
          • 2016-10-22
          • 1970-01-01
          • 2023-01-20
          • 2019-06-01
          • 2014-08-30
          • 2021-02-18
          相关资源
          最近更新 更多