WPF Правильная программная привязка для связанного ComboBox - PullRequest
2 голосов
/ 10 апреля 2011

Я работаю с приложением wpf и в настоящее время занимаюсь реализацией окна сетки свойств, аналогичного тому, которое вы можете видеть в окне свойств в Visual Studios.

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

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

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

      var attribute = (PropertyWindowAttribute) attributes[i];
           if (attribute.Enumerated)
           {
             var combo = new ComboBox();
             var binding = CreatePropertyBinding(Model.component, attribute.PropertyName);
             combo.SetBinding(Selector.SelectedItemProperty, binding);
             var enumValues =  Enum.GetNames(Model.component.GetType().GetProperty(attribute.PropertyName).PropertyType);
             foreach (var e in enumValues)
             {
                    var item = new ComboBoxItem();
                     item.Content = e;
                    combo.Items.Add(item);
             }
             propertyList.Add(new PropertyElement(attribute.DisplayName, combo));
          }
          else
          {
               var binding = CreatePropertyBinding(Model.component, attribute.PropertyName);
               var box = new TextBox();
               box.SetBinding(TextBox.TextProperty, binding);
               propertyList.Add(new PropertyElement(attribute.DisplayName, box));
                    }
         }

, и я также имеюэтот служебный метод, на который ссылаются

private static Binding CreatePropertyBinding(Component component, string path)
    {
        Binding binding = new Binding();
        binding.Path = new PropertyPath(path);
        binding.Mode = BindingMode.TwoWay;
        binding.Source = component;

        return binding;

    }

Проблема, с которой я сталкиваюсь, заключается в том, что когда я иду в свое приложение и пытаюсь изменить значение поля со списком, я получаю следующую ошибку в своем приложении

     System.Windows.Data Error: 23 : Cannot convert 'System.Windows.Controls.ComboBoxItem: Stretch' from type 'ComboBoxItem' to type 'System.Windows.HorizontalAlignment' for 'en-US' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: EnumConverter cannot convert from System.Windows.Controls.ComboBoxItem.
   at System.ComponentModel.TypeConverter.GetConvertFromException(Object value)
   at System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at System.ComponentModel.EnumConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)'
System.Windows.Data Error: 7 : ConvertBack cannot convert value 'System.Windows.Controls.ComboBoxItem: Stretch' (type 'ComboBoxItem'). BindingExpression:Path=ComponentHorizontalAlignment; DataItem='TextFieldComponent' (HashCode=31097589); target element is 'ComboBox' (Name=''); target property is 'SelectedItem' (type 'Object') NotSupportedException:'System.NotSupportedException: EnumConverter cannot convert from System.Windows.Controls.ComboBoxItem.
   at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)
   at MS.Internal.Data.ObjectTargetConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
   at System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'

Значения, которые привязаны к полям со списком, взяты из перечислений, но я не уверен, что это за исправление.

1 Ответ

2 голосов
/ 10 апреля 2011

Поскольку вы добавляете ComboBoxItems в коллекцию ComboBox.Item, то SelectedItem будет выбранным ComboBoxItem. Таким образом, вы фактически пытаетесь установить свои свойства перечисления для экземпляров ComboBoxItem.

Ваш цикл должен выглядеть следующим образом:

var enumValues =  Enum.GetValues(Model.component.GetType().GetProperty(attribute.PropertyName).PropertyType);
foreach (var e in enumValues) {
    combo.Items.Add(e);
}

Если вам нужно стилизовать ComboBoxItems, вы можете использовать ComboBox.ItemContainerStyle для установки свойств непосредственно на них. Или вы можете добавить ComboBoxItems, как вы делаете сейчас, и использовать SelectedValue и SelectedValuePath при привязке к вашей модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...