Silverlight ComboBox binding with value converter

2019-09-05 00:42发布

问题:

I'm attempting to convert the displayed value of a combobox by using its binding as a key to look for the value I would like to display. I can't seem to get it to work.

The datacontext of my user control is MyObject. MyObject has a property "MasterDrawerId", which is the Id of "MyReferencedObject".

Elsewhere in my application, accessible through a static property of my App.xaml.cs is a collection of "MyOtherObjects". "MyReferencedObject" has a foreign key relationship with the Id of "MyOtherObject".

My combobox is bound to the "MasterDrawerId", which is what's passed into the converter. I then use that as a lookup for "MyReferencedObject" to get the foreign key Id of "MyOtherObject" in order to display the name of that object.

I know it seems confusing but it's basically just using the property of the datacontext in order to do a lookup and display the name of another object in its place within a combobox.

This is my code:

masterSiteComboBox.DisplayMemberPath = "Name";
Binding binding = new Binding("MasterDrawerId");
binding.Mode = BindingMode.TwoWay;
binding.Converter = new DrwIdToSiteConverter();
masterSiteComboBox.SelectedItem = binding;
masterSiteComboBox.ItemsSource = ListOfMyOtherObjects;

Here is my converter code:

public class DrwIdToSiteConverter : IValueConverter { public DrwIdToSiteConverter() { }

    public virtual object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        XferSite site = new XferSite();

        foreach(XferUserDrawerPermissions perm in App.UserDrawerPermissions)
        {
            if (perm.DocumentTypeId.Match(value.ToString()))
            {
                site.Id = int.Parse(perm.SiteId);
                site.Name = perm.SiteName;
                break;
            }
        }

        return site;
    }

    public virtual object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }
}

I set a breakpoint at the first line of my "Convert" method of my converter and it never gets hit.

回答1:

Instead of

masterSiteComboBox.SelectedItem = binding;

do

masterSiteComboBox.SetBinding(ComboBox.SelectedItemProperty, binding);


回答2:

The selected item for a combo box must be an item that is already contained within the collection of objects that you set through the ItemsSource property. In other words, if your ItemsSource is bound to a collection of Object1, Object2, Object3, you cannot set the SelectedItem to new Object() { Name = 1 }; If you do this, you must override the Equals and GetHashCode methods. This will allow you the ability to set the SelectedItem to a new object.

Example:

public class MyObject
{
    public MyObject(string name)
    {
        if(string.IsNullOrEmpty(name)) throw new ArgumentNullException("name");
        Name = name;
    }

    public string Name { get; private set; }

    // override object.Equals
    public override bool Equals(object obj)
    {
        //       
        // See the full list of guidelines at
        //   http://go.microsoft.com/fwlink/?LinkID=85237  
        // and also the guidance for operator== at
        //   http://go.microsoft.com/fwlink/?LinkId=85238
        //

        MyObject myObj = obj as MyObject;
        if (myObj == null) return false;

        return Name == myObj.Name;
    }

    // override object.GetHashCode
    public override int GetHashCode()
    {
        return Name.GetHashCode;
    }
}

var items = new List<MyObject>()
            {
                new MyObject {Name = "One"},
                new MyObject {Name = "Two"},
                new MyObject {Name = "Three"},
            };

// Converter code
return new MyObject {Name = "One"};