Silverlight DataGridColumn AttachedProperties

Я пытаюсь создать AttachedProperty для DataGridColumn в Silverlight 3.0, и у меня возникают некоторые проблемы.

Вот прикрепленное свойство:

public class DataGridColumnHelper
{
    public static readonly DependencyProperty HeaderProperty =
        DependencyProperty.RegisterAttached("Header", typeof(string), typeof(DataGridColumnHelper),
                                            new PropertyMetadata(OnHeaderPropertyChanged));

    private static void OnHeaderPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        string header = GetHeader(d);

        var dataGridColumn = d as DataGridColumn;

        if (dataGridColumn == null)
        {
            return;
        }

        dataGridColumn.Header = GetHeader(dataGridColumn);
    }

    public static string GetHeader(DependencyObject obj)
    {
        return (string)obj.GetValue(HeaderProperty);
    }

    public static void SetHeader(DependencyObject obj, string value)
    {
        obj.SetValue(HeaderProperty, value);
    }

}

Как видите, это очень просто, я пытаюсь преодолеть ограничение, заключающееся в том, что свойство Header в классе DataGridColumn не может быть привязано.

Этот XAML работает так, как ожидалось...

<Controls:DataGridTextColumn Binding="{Binding OwnerName}"                                                                         
                         HeaderStyle="{StaticResource DataGridColumnHeaderStyle}"

                         Behaviors:DataGridColumnHelper.Header="User Name"/>

Однако этот XAML выдает ошибку... (в частности: {System.Windows.Markup.XamlParseException: AG_E_PARSER_PROPERTY_NOT_FOUND [строка: 224, позиция: 112] в System.Windows.Application.LoadComponent(компонент объекта, Uri resourceLocator)....} )

<Controls:DataGridTextColumn Binding="{Binding OwnerName}"                                                                         
                         HeaderStyle="{StaticResource DataGridColumnHeaderStyle}"

                         Behaviors:DataGridColumnHelper.Header="{Binding Resources.UserNameListViewHeading, Source={StaticResource Labels}}"/>

Просто для эксперимента я прикрепил это свойство (с приведенным выше синтаксисом привязки) к DataGrid и проверил свойство DataGridColumnHelper.Header в методе OnHeaderPropertyChanged, и значение было правильным (и исключение не было выдано)

Насколько я понимаю, объект, к которому присоединено свойство AttachedProperty, должен быть DependencyProperty. Просматривая Reflector, DataGridColumn (от которого происходит DataGridTextColumn) происходит от DependencyProperty.

Может кто-нибудь, пожалуйста, пролить свет на это? Я пытаюсь локализовать наше приложение, и у меня возникают проблемы с DataGrid. Я уверен, что могу сделать это в коде программной части, но я пытаюсь этого избежать.


person Chris Mancini    schedule 27.10.2009    source источник


Ответы (2)


Крис, проблема очень проста, это не сработает, потому что DataGridTextColumn "отсоединен" от визуального дерева. Ваш объект DataGridTextColumn укоренен в коллекции Columns DataGrid — см. косвенность. Таким образом, даже прикрепленные свойства не будут работать так, как вы ожидаете. Теперь есть способ заставить все это работать, используя то, что я называю прикрепленными привязками, см.:

http://www.orktane.com/Blog/post/2009/09/29/Introduction-nRouteToolkit-for-Silverlight-(Part-I).aspx

Просто не забудьте прикрепить свойства привязки, используя что-то, что находится в VisualTree (так что Grid, содержащий столбец, вполне подойдет).

Надеюсь это поможет.

person Rishi    schedule 04.11.2009
comment
Я следил за вашими сообщениями о nRoute Toolkit и с нетерпением жду возможности поэкспериментировать с ним. Спасибо за описательный ответ. - person Chris Mancini; 07.11.2009
comment
А как насчет Run in Silverlight? Прикрепленное свойство с привязкой к Run не работает в SIlverlight... - person Michael Sync; 11.05.2010

Попробуйте использовать это, я предполагаю, что UserName является свойством в вашей модели представления.

    <Controls:DataGridTextColumn Binding="{Binding OwnerName}"                                                                         
HeaderStyle="{StaticResource DataGridColumnHeaderStyle}"
Behaviors:DataGridColumnHelper.Header="{Binding UserName}"/>

Я не могу проверить ваш сценарий, поэтому мой пост - просто идея. Может работать, может нет.

person Neil    schedule 28.10.2009
comment
Привязка, которую я пытаюсь использовать, взята из файла ресурсов, потому что мы локализуем наши строки. Привязка DataGridTextColumn основана на источнике Items (при условии, что мы не указываем источник, как в приведенном выше примере), поэтому DataContext не совпадает с DataGrid. Спасибо - person Chris Mancini; 28.10.2009