none
Binding к Атрибуту RRS feed

  • Вопрос

  • Подскажите, как создать биндинг к атрибуту массива в DataGrid.  В datagrid.ItemSourse передается List<double[x]> у каждого массива есть атрибут, например [Description]. В первом столбце нужно выводить этот дескрипшн. 

    Первый столбец создан через XAML. Остальные формируются динамически в коде. С ними проблем нет а вот в первом вывести подписи к данным не получается. Переделать все в  List<string[x + 1]> нельзя т.к. данные редактируемые и используется двусторонний биндинг.

Ответы

  • Добрый день.

    К атрибуту биндинг сделать не получится. Как вариант, воспользуйтесь паттерном "декоратор". Если на пальцах, то введите дополнительный класс, в котором будет свойство типа double[x] и свойство, которое будет возвращать атрибут массива.

    Соответственно биндинг первого столбца будет к свойству извлекающему атрибут, биндинг остальных к вашему массиву.

    • Предложено в качестве ответа Abolmasov Dmitry 3 июля 2012 г. 7:43
    • Помечено в качестве ответа Abolmasov Dmitry 4 июля 2012 г. 8:18
    Отвечающий
  • Мне откровенно говоря такую задачу решать не приходилось, но так примерно думается, что можно пустить привязку к массиву и задать конвертер, в котором извлекать атрибут. Вы же можете извлечь атрибут массива в коде? Если да, то это можно сделать в конвертере.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    • Изменено LXGDARKEditor 3 июля 2012 г. 7:05
    • Предложено в качестве ответа Brash_O 3 июля 2012 г. 7:29
    • Помечено в качестве ответа Abolmasov Dmitry 4 июля 2012 г. 8:18
    Отвечающий
  • К сожалению получить атрибут в конвертере не удалось пришлось использовать "декоратор"
    • Помечено в качестве ответа firefox0013 4 июля 2012 г. 10:06
    4 июля 2012 г. 10:06

Все ответы

  • Добрый день.

    К атрибуту биндинг сделать не получится. Как вариант, воспользуйтесь паттерном "декоратор". Если на пальцах, то введите дополнительный класс, в котором будет свойство типа double[x] и свойство, которое будет возвращать атрибут массива.

    Соответственно биндинг первого столбца будет к свойству извлекающему атрибут, биндинг остальных к вашему массиву.

    • Предложено в качестве ответа Abolmasov Dmitry 3 июля 2012 г. 7:43
    • Помечено в качестве ответа Abolmasov Dmitry 4 июля 2012 г. 8:18
    Отвечающий
  • Мне откровенно говоря такую задачу решать не приходилось, но так примерно думается, что можно пустить привязку к массиву и задать конвертер, в котором извлекать атрибут. Вы же можете извлечь атрибут массива в коде? Если да, то это можно сделать в конвертере.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    • Изменено LXGDARKEditor 3 июля 2012 г. 7:05
    • Предложено в качестве ответа Brash_O 3 июля 2012 г. 7:29
    • Помечено в качестве ответа Abolmasov Dmitry 4 июля 2012 г. 8:18
    Отвечающий
  • Мне откровенно говоря такую задачу решать не приходилось, но так примерно думается, что можно пустить привязку к массиву и задать конвертер, в котором извлекать атрибут. Вы же можете извлечь атрибут массива в коде? Если да, то это можно сделать в конвертере.

    Кстати да, можно попробовать конвертором.

    Отвечающий
  • Уважаемый пользователь, пожалуйста не бросайте тему без ответа. Если чье-либо сообщение решает вашу проблему, то, пожалуйста, отметьте его как ответ. Для этого под сообщением есть кнопка 'Пометить как ответ'.

    Если вы сами решили проблему, то будет очень хорошо если вы расскажите решение другим пользователям.

    Спасибо.


    Для связи [mail]

  • Мне откровенно говоря такую задачу решать не приходилось, но так примерно думается, что можно пустить привязку к массиву и задать конвертер, в котором извлекать атрибут. Вы же можете извлечь атрибут массива в коде? Если да, то это можно сделать в конвертере.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    На сколько я вас понял надо использовать IValueConverter? И биндинг типа:
    <DataGridTextColumn Binding="{Binding Converter={StaticResource DescriptionConverter}}" />


  • Да, вы должны использовать IValueConverter. Зачем вам ObjectDataProvider я не очень понял. Покажите, как у вас выглядит биндинг в вашем DataGrid, а я вам покажу, как написать ValueConvertor.

    Что нужно:

    1. Класс объекты которого у вас отображаются.

    2. Полная разметка DataGrid-а


    Отвечающий
  • На сколько я вас понял надо использовать IValueConverter? И биндинг типа:
    <DataGridTextColumn Binding="{Binding Converter={StaticResource DescriptionConverter}}" />



    Да, порхоже.
    Отвечающий
  • Сам ДатаГрид

    <DataGrid AutoGenerateColumns="False" Name="TableGrid_Prop" CanUserAddRows="False" CanUserSortColumns="False" AllowDrop="False" Margin="0,5,5,5" CellEditEnding="TableGrid_Prop_CellEditEnding" SelectedCellsChanged="TableGrid_Prop_SelectedCellsChanged">
    
    <DataGrid.Columns>
    
    <DataGridTextColumn Header="Показатель" x:Name="TestColumn" IsReadOnly="True" Binding="{Binding Converter={StaticResource DescriptionConverter}}"></DataGridTextColumn>
    
    </DataGrid.Columns>
    
    </DataGrid>

    Его заполнение:

    List<double[]> TableGrid_Proplist = new List<double[]>();
    
    TableGrid_Proplist.Add(pad.1);
    
    TableGrid_Proplist.Add(pad.2);
    
    TableGrid_Proplist.Add(pad.3);
    
    TableGrid_Prop.ItemsSource = TableGrid_Proplist;

    Создал конвертер. Конвертер находится внутри класса окна. Почему то при попытке отобразить окно возникает ошибка "Не удается найти статический ресурс". Не могу понять почему.

    public class DescriptionConverter : IValueConverter
    
    {
    
    private string GetDescription(double[] enumObj)
    
    {
    
    FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
    
    object[] attribArray = fieldInfo.GetCustomAttributes(false);
    
    if (attribArray.Length == 0)
    
    {
    
    return enumObj.ToString();
    
    }
    
    else
    
    {
    
    CommonAttribute attrib = attribArray[0] as CommonAttribute;
    
    return attrib.Description;
    
    }
    
    }
    
    object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
    
    {
    
    double[] myEnum = (double[])value;
    
    string description = GetDescription(myEnum);
    
    return description;
    
    }
    
    object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    
    {
    
    return string.Empty;
    
    }
    
    }

    3 июля 2012 г. 10:15
  • А вы статикресурс объявили?

    Почситайте вот здесь, как можно работать с конверторами в WPF.

    3 июля 2012 г. 10:42
    Отвечающий
  • Проблему с ресурсом решил. Большое спасибо! 

    Не получается получить атрибут

    FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());

     

    fieldinfo == null;

    На сколько я понимаю атрибут из переменной получается именно так?

  • Дело в том, что атрибут получается не от переменной, а от класса, метода, события, свойства или поля. Получение атрибута выполняется вот так:

    Attribute attr = property.GetCustomAttribute(typeof(RequiredAttribute));
    

    Где property имеет тип PropertyInfo, а RequiredAttribute класс атрибута, который мы пытаемся у свойства извлечь. Вот, посмотрите статью про применение атрибутов.

    P.s. На будущее, если ваш вопрос не относится к основной теме топика, лучше его задавать в отдельном топике.

    Отвечающий
  • К сожалению получить атрибут в конвертере не удалось пришлось использовать "декоратор"
    • Помечено в качестве ответа firefox0013 4 июля 2012 г. 10:06
    4 июля 2012 г. 10:06