【问题标题】:DataGridTextColumn - How to bind IsReadonly?DataGridTextColumn - 如何绑定 IsReadonly?
【发布时间】:2011-05-08 10:20:45
【问题描述】:

在 Silverlight 4 中,DataGridTextColumn 的 IsReadOnly 属性似乎没有依赖属性。因此我无法将它绑定到视图模型上的属性。

似乎唯一的选择是使用 DataTemplate,但即使在这里我也面临两个主要问题:

<sdk:DataGrid Style="{StaticResource DataGridStyle}" x:Name="call_dataGrid" ItemsSource="{Binding Calls}">
                    <sdk:DataGrid.Columns>
                        <sdk:DataGridTextColumn Header="Call Time" Binding="{Binding Path=CallTime}" />
                        <sdk:DataGridTemplateColumn Header="Call Date">
                            <sdk:DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <TextBox Text="{Binding Path=CallDate}" IsReadOnly="{Binding Path=DataContext.IsInEditMode, ElementName=call_dataGrid, Converter={StaticResource NegationConverter}}"/>
                                </DataTemplate>
                            </sdk:DataGridTemplateColumn.CellEditingTemplate>
                        </sdk:DataGridTemplateColumn>

我似乎无法编辑 DataGridTextColumn 的模板,而必须使用 DataGridTemplateColumn,如上所示。然而,这会覆盖我之前在 DataGridStyle 中定义的所有样式。我的列甚至没有行标记,看起来与其他单元格完全不同。

第二个问题是,它仍然无法按预期工作。该模板内的文本框仍未设置为只读。我在这里做错了什么?

非常感谢您对此提供的帮助,

更新

在下面有希望的响应之后,我调整了代码但没有成功。

我已将DP的回调改成如下

public class IsReadOnlyDpAttachable
    {
        public static void SetIsReadXOnly(DependencyObject obj, bool isReadOnly)
        {
            obj.SetValue(IsReadXOnlyProperty, isReadOnly);
        }

        public static bool GetIsReadXOnly(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsReadXOnlyProperty);
        }

        public static readonly DependencyProperty IsReadXOnlyProperty =
            DependencyProperty.RegisterAttached("IsReadXOnly", typeof(bool), typeof(IsReadOnlyDpAttachable), new PropertyMetadata(false, Callback));

        private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((DataGrid)d).IsReadOnly = (bool)e.NewValue;
        }
    }

并在 DataGrid 的 IsReadOnly 本身上设置 DP,它工作得非常好,但是在这里我再次不需要它,因为这里的 IsReadOnly 已经是一个 Dp 并且无论如何都可以轻松绑定。但测试表明 Dp 工作正常:

<sdk:DataGrid PrismExt:IsReadOnlyDpAttachable.IsReadXOnly="{Binding IsInEditMode, Mode=TwoWay, Converter={StaticResource NegationConverter}}" Style="{StaticResource DataGridStyle}" CanUserReorderColumns="True" x:Name="call_dataGrid" AutoGenerateColumns="False" ItemsSource="{Binding Calls}">

但是,当我尝试在底层 DataGridTextColumn 上使用 DP 时,它什么也没做:

<Grid x:Name="LayoutRoot">
<sdk:DataGrid Style="{StaticResource DataGridStyle}" CanUserReorderColumns="True" x:Name="call_dataGrid" AutoGenerateColumns="False" ItemsSource="{Binding Calls}">
                    <sdk:DataGrid.Columns>                        
                        <sdk:DataGridTextColumn Header="Call Time" Binding="{Binding Path=CallTime}" PrismExt:IsReadOnlyDpAttachable.IsReadXOnly="{Binding DataContext.IsInEditMode, ElementName=LayoutRoot, Mode=TwoWay, Converter={StaticResource NegationConverter}}"/>
                    </sdk:DataGrid.Columns>
</sdk:DataGrid>
</Grid>

有什么想法吗?

【问题讨论】:

    标签: silverlight silverlight-4.0


    【解决方案1】:

    您可以做的是创建一个附加属性来处理 DataGridTextColumn 中 IsReadOnly 属性的更改。

    public class Class1
    {
        public static void SetIsReadOnly(DependencyObject obj, bool isReadOnly)
        {
            obj.SetValue(IsReadOnlyProperty, isReadOnly);
        }
    
        public static bool GetIsReadOnly(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsReadOnlyProperty);
        }
    
        // Using a DependencyProperty as the backing store for MyProperty.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsReadOnlyProperty =
            DependencyProperty.RegisterAttached("IsReadOnly", typeof(bool), typeof(Class1), new PropertyMetadata(false, Callback));
    
        private static void Callback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((DataGridTextColumn)d).IsReadOnly = (bool)e.NewValue;
        }
    }
    

    在您的 xaml 中,您可以只使用附加属性。

    <sdk:DataGridTextColumn local:Class1.IsReadOnly="True" Binding="{Binding Property1}" Header="Property1"/>
    

    希望这会有所帮助。 :)

    更新

    一旦有了 DataContextProxy 类,就可以了

            <sdk:DataGridTextColumn Binding="{Binding Name}"
                                    local:Class1.IsReadOnly="{Binding DataSource.IsInEditMode, Source={StaticResource DataContextProxy}, Converter={StaticResource xxxConverter}}"
                                    Header="ReadOnly Header" />
    

    【讨论】:

    • 非常感谢您的回复。但是,虽然正常的真或假有效,但我仍然无法使用这样的绑定:
    • 你能在你的 NegationConverter 中放一个断点,看看它是否被调用了吗?
    • 好的,我知道问题出在哪里。我假设您的属性 IsInEditMode 位于 DataGrid 的数据上下文中,但不在 DataGridTextColumn 的数据上下文中。所以你需要在你的页面上命名你最顶层的元素。假设它是一个Grid,叫做'LayoutRoot',那么你需要使用ElementBinding来获取父DataContext,像这样,
    • Kave,我很抱歉,ElementName 绑定实际上无法在数据网格单元格中工作。您需要查看这篇文章以包含 DataContextProxy。 weblogs.asp.net/dwahlin/archive/2009/08/20/…我会在几秒钟内更新我的答案。
    • 我还在这里更新了一个示例项目以防万一。 cid-f9ac8aa3f6afdcc3.office.live.com/self.aspx/Public/…
    猜你喜欢
    • 1970-01-01
    • 2011-12-21
    • 2014-09-13
    • 2013-11-15
    • 2013-06-15
    • 1970-01-01
    • 2012-05-23
    • 2014-09-23
    • 2012-04-29
    相关资源
    最近更新 更多