开发者

WPF Correct programatic binding for bound ComboBox

I am working with a wpf application, and am currently in the process of implementing a property grid box, similar to one you might see in the properties window in Visual Studios.

I am populating this property window dynamically when items in my application are selected using reflection, but this means I must create the input method dynamically as well.(textbox,checkbox,combo box) depending on the type of property.

Since this is generated dynamically, I am forced to create these items programmatically.

I have the following code that determines if it is to generate a textbox, or a combo box from the property, and then it binds the combo box.

      var attribute = (PropertyWindowAttribute) attributes[i];
           if (attribute.Enumerated)
           {
             var combo = new ComboBox();
             var binding = CreatePropertyBinding(Model.component, attribute.开发者_Go百科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));
                    }
         }

and I also have this utility method which is being referenced

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;

    }

The problem I am having is when I go to my application, and try to change the value of a combo box, I get the following error output in my application

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

The values that are being bound to the combo boxes come from enums, but I am not sure what the fix is for this.


Since you are adding ComboBoxItems to the ComboBox.Item collection, then SelectedItem would be the ComboBoxItem that is selected. So you are effectively trying to set your enumeration properties to an instances of ComboBoxItem.

Your loop should look like this instead:

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

If you need to Style the ComboBoxItems, you can use the ComboBox.ItemContainerStyle to set properties directly on them. Or you could add the ComboBoxItems like you do now, and use SelectedValue and SelectedValuePath when binding to your model.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜