简体   繁体   中英

WPF ComboBox Binding with Converter

Ok, here's the deal. I have a CollectionViewSource:

<CollectionViewSource x:Key="PA_System_AppStatus">
    <CollectionViewSource.Source>
        <SystemCols:ArrayList>
            <ComboBoxItem Content="Active" />
            <ComboBoxItem Content="Denied" />
            <ComboBoxItem Content="Granted" />
        </SystemCols:ArrayList>
    </CollectionViewSource.Source>
</CollectionViewSource>

I also have a ComboBox bound to that:

                <ComboBox x:Name="Perro" Tag="Application"
                          SelectedValue="{Binding Path=[AppStatus], Converter={StaticResource AppStatusConverter}}"
                          ItemsSource="{Binding Source={StaticResource PA_System_AppStatus2}}"/>

AppStatus is a char in a DataRow that may be A,D,G. Therefore, I want the ComboBox to display the whole ComboBoxItem above, but under the hood store in the field the char. For that, I wrote this Converter:

 public class AppStatusConverter : IValueConverter
    {
        public object Convert(
            object value,
            System.Type targetType,
            object parameter,
            System.Globalization.CultureInfo culture
            )
        {
            string returnValue = null;

            if (value != System.DBNull.Value && value != null)
            {
                if ((string)value == "A")
                    returnValue = "Active";
                else if ((string)value == "D")
                    returnValue = "Denied";
                else if ((string)value == "G")
                    returnValue = "Granted";
                else
                    returnValue = null;
            }
            return returnValue;
        }

        public object ConvertBack(
            object value,
            System.Type targetType,
            object parameter,
            System.Globalization.CultureInfo culture
            )
        {
            string returnValue = null;

            string tempvalue = ((ComboBoxItem)value).Content.ToString();

            if (tempvalue == "Active")
                returnValue = "A";
            else if (tempvalue == "Denied")
                returnValue = "D";
            else if (tempvalue == "Granted")
                returnValue = "G";

            else
                returnValue = null;

            return returnValue;
        }
    }

The ConvertBack part works perfectly and, whenever I choose a value, the DataRow gets filled with one of the chars (A,D or G).

However, the Convert does not. For instance, I load a DataRow from a DB. The Converter then correctly takes the value inside the 'AppStatus' column and tries to convert it to select one of the ComboBox Items and assign the SelectedValue. However, nothing happens.

It seems that the problem is that you are returning a string value from the converter, but the ItemsSource is an ArrayList populated with ComboBoxItems, so it checks if the reference is the same. Try to populate your ArrayList with string values instead of ComboBoxItems. You could use a normal string array for this:

<x:Array Type="sys:String">
  <sys:String>Active</sys:String>
  <sys:String>Denied</sys:String>
  <sys:String>Granted</sys:String>
</x:Array>

where you add the system namespace: xmlns:sys="clr-namespace:System;assembly=mscorlib" You could then simplify your converter as follows:

Convert:

{
  if (!(value is char)) return null;
  char c = (char)value;

  switch (c)
  {
    case 'A': return "Active";
    case 'D': return "Denied";
    case 'G': return "Granted";
  }

  return null;
}

ConvertBack:

{
  string sVal = value as string;
  if (string.IsNullOrEmpty(sVal)) return null;

  switch (sVal)
    {
      case "Active": return 'A';
      case "Denied": return 'D';
      case "Granted": return 'G';
    }

    return null;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM