Wpf 将组合框绑定到静态查找表,并将当前项绑定到用户控件类lookupID
我有一个静态类,它为我提供列表的查找表(ObservableCollectoins)。 (例如城市列表) 这是XAML-但是如何将其绑定到Person CityID?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中的
<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>