Wpf 将组合框绑定到静态查找表,并将当前项绑定到用户控件类lookupID

Wpf 将组合框绑定到静态查找表,并将当前项绑定到用户控件类lookupID,wpf,binding,Wpf,Binding,我有一个静态类,它为我提供列表的查找表(ObservableCollectoins)。 (例如城市列表) 这是XAML-但是如何将其绑定到Person CityID? <ComboBox Name="cbxCity" DisplayMemberPath="CityName" SelectedValuePath="CityID" SelectedItem="{Binding Path=CityID}" Width="80"></ComboBox> 如果您将XAMl中的

我有一个静态类,它为我提供列表的查找表(ObservableCollectoins)。 (例如城市列表)

这是XAML-但是如何将其绑定到Person CityID?

<ComboBox Name="cbxCity"  DisplayMemberPath="CityName" SelectedValuePath="CityID" SelectedItem="{Binding Path=CityID}" Width="80"></ComboBox>


如果您将XAMl中的SelectedItem更改为SelectedValue,它是否有效?

这当然是可能的,可以通过几种方法实现。下面的解决方案使用
IValueConverter
。还请注意,我在
City
类中重写了
Equals
GetHashCode
,因为返回城市列表的静态类每次都创建一个新实例

后面的代码如下所示,只是一个示例,没有经过彻底测试;不管它如何满足你的需要

    public partial class Window1 : Window
    {
        private Data _data = new Data();

        public Window1()
        {
            InitializeComponent();

            this.DataContext = _data;
        }
    }

    public class Data
    {
        private Person _person = new Person() { CityId = 3 };
        public Person Person
        {
            get
            {
                return _person;
            }
        }

        public ObservableCollection<City> Citys
        {
            get
            {
                return GeneralData.Citys;
            }
        }
    }

    public class Person : INotifyPropertyChanged
    {
        private int _cityId = -1;
        public int CityId
        {
            get
            {
                return _cityId;
            }
            set
            {
                _cityId = value;
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("CityId"));

                Console.WriteLine("My new CityId is: " + _cityId);
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

    public class City : INotifyPropertyChanged
    {
        private String _cityName = "N/A";
        public String CityName
        {
            get
            {
                return _cityName;
            }
            set
            {
                _cityName = value;
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("CityName"));
            }
        }

        private int _cityId = -1;
        public int CityId
        {
            get
            {
                return _cityId;
            }
            set
            {
                _cityId = value;
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("CityId"));
            }
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            City c = obj as City;
            if (c == null)
            {
                return false;
            }

            return this.CityId == c.CityId && String.Compare(this.CityName, c.CityName, true) == 0;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode() ^ CityId;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

    public static class GeneralData
    {
        public static ObservableCollection<City> Citys
        {
            get
            {
                ObservableCollection<City> citites = new ObservableCollection<City>{
                    new City { CityId = 1, CityName = "Denver" },
                    new City { CityId = 2, CityName = "Phoenix" },
                    new City { CityId = 3, CityName = "San Diego" },
                    new City { CityId = 4, CityName = "Pasadena" },
                    new City { CityId = 5, CityName = "Sedona" }};

                return citites;
            }
        }
    }

    public class CityConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int cityId = (int)value;
            return GeneralData.Citys.Single(i => i.CityId == cityId);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            City c = (City)value;
            return c.CityId;
        }

        #endregion
    }
公共部分类窗口1:窗口
{
私有数据_Data=新数据();
公共窗口1()
{
初始化组件();
this.DataContext=\u数据;
}
}
公共类数据
{
私人(个人=新人){CityId=3};
公众人物
{
得到
{
返回人;
}
}
公共可观测收集城市
{
得到
{
返回GeneralData.Citys;
}
}
}
公共类人员:INotifyPropertyChanged
{
private int_cityId=-1;
公共国际城市ID
{
得到
{
返回城市ID;
}
设置
{
_cityId=值;
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
处理人(此,新的PropertyChangedEventArgs(“CityId”);
Console.WriteLine(“我的新CityId是:”+\u CityId);
}
}
#区域INotifyProperty更改成员
公共事件属性更改事件处理程序属性更改;
#端区
}
公共类城市:InotifyProperty已更改
{
私有字符串\u cityName=“N/A”;
公共字符串城市名称
{
得到
{
return_cityName;
}
设置
{
_cityName=值;
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
处理人(这是新的PropertyChangedEventArgs(“CityName”);
}
}
private int_cityId=-1;
公共国际城市ID
{
得到
{
返回城市ID;
}
设置
{
_cityId=值;
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null)
处理人(此,新的PropertyChangedEventArgs(“CityId”);
}
}
公共覆盖布尔等于(对象对象对象)
{
if(obj==null)
返回false;
城市c=作为城市的obj;
如果(c==null)
{
返回false;
}
返回this.CityId==c.CityId&&String.Compare(this.CityName,c.CityName,true)==0;
}
公共覆盖int GetHashCode()
{
返回base.GetHashCode()^CityId;
}
#区域INotifyProperty更改成员
公共事件属性更改事件处理程序属性更改;
#端区
}
公共静态类GeneralData
{
公共静态可观测收集城市
{
得到
{
ObservableCollection citites=新的ObservableCollection{
新城{CityId=1,CityName=“丹佛”},
新城{CityId=2,CityName=“凤凰城”},
新城{CityId=3,CityName=“圣地亚哥”},
新城{CityId=4,CityName=“Pasadena”},
新城{CityId=5,CityName=“Sedona”};
归还公民;
}
}
}
公共类城市转换器:IValueConverter
{
#区域转换器成员
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
int cityId=(int)值;
返回GeneralData.Citys.Single(i=>i.CityId==CityId);
}
公共对象转换回(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
城市c=(城市)值;
返回c.CityId;
}
#端区
}
XAML是短而简单的

<Window.Resources>
        <local:CityConverter x:Key="CityConverter"/>
    </Window.Resources>

    <Grid>
        <ComboBox ItemsSource="{Binding Citys}"
                  DisplayMemberPath="CityName"
                  SelectedItem="{Binding Person.CityId, Converter={StaticResource CityConverter}}">
        </ComboBox>
    </Grid>


首先-感谢您的详细回答。城市是一个实体框架对象,但我可能可以扩展它。我会试试。为什么我需要重写Equal和GetHashCode?转换器不使用它们。。它检查cityId?@Dani,用于启动时的初始转换;返回一个城市实例;该实例将不同于有界实例;因此,覆盖。如果您不关心启动或希望手动设置,则可以取消覆盖。看起来它完全忽略了SelectedItem=part。。。如果我键入Person.CityID或kukuriku.CityID,则不会发生任何事情,并且转换器不会被命中……如果要更改组合框中的选择,则会调用Person.CityID setter来执行转换器的ConvertBack方法。注意控制台out…console.WriteLine(“我的新CityId是:”+CityId);当值来自Person.CityId.nope时,Convert在启动时调用一次,结果相同,组合框绑定,但当前项不是。它实际上是解决方案的一部分。
    public partial class Window1 : Window
    {
        private Data _data = new Data();

        public Window1()
        {
            InitializeComponent();

            this.DataContext = _data;
        }
    }

    public class Data
    {
        private Person _person = new Person() { CityId = 3 };
        public Person Person
        {
            get
            {
                return _person;
            }
        }

        public ObservableCollection<City> Citys
        {
            get
            {
                return GeneralData.Citys;
            }
        }
    }

    public class Person : INotifyPropertyChanged
    {
        private int _cityId = -1;
        public int CityId
        {
            get
            {
                return _cityId;
            }
            set
            {
                _cityId = value;
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("CityId"));

                Console.WriteLine("My new CityId is: " + _cityId);
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

    public class City : INotifyPropertyChanged
    {
        private String _cityName = "N/A";
        public String CityName
        {
            get
            {
                return _cityName;
            }
            set
            {
                _cityName = value;
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("CityName"));
            }
        }

        private int _cityId = -1;
        public int CityId
        {
            get
            {
                return _cityId;
            }
            set
            {
                _cityId = value;
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs("CityId"));
            }
        }

        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;

            City c = obj as City;
            if (c == null)
            {
                return false;
            }

            return this.CityId == c.CityId && String.Compare(this.CityName, c.CityName, true) == 0;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode() ^ CityId;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion
    }

    public static class GeneralData
    {
        public static ObservableCollection<City> Citys
        {
            get
            {
                ObservableCollection<City> citites = new ObservableCollection<City>{
                    new City { CityId = 1, CityName = "Denver" },
                    new City { CityId = 2, CityName = "Phoenix" },
                    new City { CityId = 3, CityName = "San Diego" },
                    new City { CityId = 4, CityName = "Pasadena" },
                    new City { CityId = 5, CityName = "Sedona" }};

                return citites;
            }
        }
    }

    public class CityConverter : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            int cityId = (int)value;
            return GeneralData.Citys.Single(i => i.CityId == cityId);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            City c = (City)value;
            return c.CityId;
        }

        #endregion
    }
<Window.Resources>
        <local:CityConverter x:Key="CityConverter"/>
    </Window.Resources>

    <Grid>
        <ComboBox ItemsSource="{Binding Citys}"
                  DisplayMemberPath="CityName"
                  SelectedItem="{Binding Person.CityId, Converter={StaticResource CityConverter}}">
        </ComboBox>
    </Grid>