DataGridTextColumn - Как связать IsReadonly? - PullRequest
5 голосов
/ 08 мая 2011

В Silverlight 4 свойство IsReadOnly объекта DataGridTextColumn не является свойством зависимости. Следовательно, я не мог связать его со свойством модели представления.

Кажется, единственной альтернативой является использование 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;
        }
    }

И установите DP на самом IsReadOnly DataGrid, он работает отлично, но опять же здесь мне это не понадобится, поскольку IsReadOnly здесь уже является 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}">

Однако в тот момент, когда я пытаюсь использовать DP в базовом DataGridTextColumn, он ничего не делает:

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

Есть идеи?

1 Ответ

7 голосов
/ 08 мая 2011

что вы можете сделать, это создать присоединенное свойство для обработки изменения свойства IsReadOnly в DataGridTextColumn.

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" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...