1
votes

For skimmers. The question is near the bottom just after the bold text.

I am data-binding a ComboBox to an enumeration type using an ObjectDataProvider. The ObjectDataProvider is very simple.

<ObjectDataProvider x:Key="FaultAreaValues" 
                    ObjectType="{x:Type FaultTrackCoreDBValues:FaultAreas}"
                    MethodName="GetValues">

    <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="FaultTrackCoreDBValues:FaultAreas" />
    </ObjectDataProvider.MethodParameters>

</ObjectDataProvider>

I data-bind the ComboBox via ItemsSource, which is also simple.

ItemsSource="{Binding Source={StaticResource FaultAreaValues}}"

All of this works fine. The ComboBox is populated with the proper values from the enumeration. I am also using the MVVM Pattern, so the view's DataContext is set to an instance of its associated ViewModel, which looks (trimmed down) like this.

public class ViewModel : INotifyPropertyChanged
{
    private IFault _Fault;

    public IFault Fault {
        get {
            return _Fault;
        }
        set {
            _Fault = value;
            OnPropertyChanged("Fault");
        }
    }
}

And the Model:

public interface IFault
{
    FaultAreas Area { get; set; }
}

public partial class Fault : IFault, INotifyPropertyChanged
{
    FaultAreas IFault.Area {
        get {
            return (FaultAreas)Area;
        }
        set {
            Area = (Int32)value;
        }
    }
}

It is important to note that Fault is a partial class that is actually an Entity in an Entity Data Model. Because Entity does not support enumerations prior to .NET 4.5 and Entity Framework 4.5, I use an explicit interface to add that support, as well as completely decouple everything from knowing anything about the Entity objects.

Here is the actual SelectedItem binding:

SelectedItem="{Binding Fault.Area}"

The problem is that the selection of the ComboBox is never initially set, and changing the selection causes the adorner to show, and causes the following exception:

System.Windows.Data Error: 23 : Cannot convert 'Behavior' from type 'FaultAreas' to type 'System.Int32' for 'en-US' culture with default conversions; consider using Converter property of Binding. NotSupportedException:'System.NotSupportedException: Int32Converter cannot convert from FaultTrack.Core.DBValues.FaultAreas. at System.ComponentModel.TypeConverter.GetConvertFromException(Object value) at System.ComponentModel.TypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value) at System.ComponentModel.BaseNumberConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value) at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)'

I'm not sure what causes this. I can solve the error by binding to a FaultAreas property directly on the ViewModel, but that's not what I want to do. I want to bind to the instance of the model IFault, and understand why this error happens.

1

1 Answers

1
votes

It works for me when I change you code a little bit.

public partial class Fault : IFault, INotifyPropertyChanged
{
    private FaultAreas _area;
    public FaultAreas Area 
    {
        get { return (FaultAreas)_area; }
        set 
        {
            _area= value;
            OnPropertyChanged("Area");
        }
   }
 }

I can see initial value and binding the selecteditem works too. I just change the interface implementation and call OnPropertyChanged("Area"); .

EDIT: It also works with explicit interface implementation

public partial class Fault : IFault, INotifyPropertyChanged
{
    private int Area;

    public Fault()
    {
        Area = 0;//default?
    }

    FaultAreas IFault.Area
    {
        get{ return (FaultAreas)Area; }
        set
        {
            Area = (int)value;
            OnPropertyChanged("Area");
        }
    }
 }

the binding looks like the following then:

 SelectedItem="{Binding Path=Fault.(local:IFault.Area)}"