Wpf 与项目模板的组合框数据绑定
我正在尝试创建一个包含魔兽世界物品列表的wpf组合框。我正在为组合框使用项目模板,以便在组合框下拉列表中显示项目图标和项目名称。它按原样工作,我可以开始键入项目名称,弹出窗口中的项目列表将自动过滤 问题是,当我单击某个项目时,我希望该项目的名称显示在组合框文本区域中。相反,我得到的是一个非常简短的ItemDisplayModel.ToString(),然后是一个空字符串 ItemDisplayModel.ToString()是我从列表中选择的ItemDisplayModel类型。这是有意义的,因为combobox控件ItemsSource属性包含ItemDisplayModel类型的数组 但在我的AuctionHouseFilterItemModel.Value属性中,我正在检测值是否已更改,如果已更改,则重建要显示在组合框中的项目列表。因此,因为当我单击弹出列表中的项目时,组合框中的文本被更改为ItemDisplayModel.ToString(),所以它再次重建项目列表,但这次没有匹配,因为ItemDisplayModel.ToString()与任何已知的项目名称都不匹配 我所要做的只是在单击弹出列表中的项目时,我希望ItemDisplayModel.Name映射到AuctionHouseFilterItemModel.Value属性,并使combobox文本区域显示AuctionHouseFilterItemModel.Value 这有意义吗?我尝试了许多不同的方法,但我不知所措。环顾网络也没有给我答案。我相信这是一个简单的解决办法,但我无法找到解决办法 这是我的XAML控件Wpf 与项目模板的组合框数据绑定,wpf,combobox,Wpf,Combobox,我正在尝试创建一个包含魔兽世界物品列表的wpf组合框。我正在为组合框使用项目模板,以便在组合框下拉列表中显示项目图标和项目名称。它按原样工作,我可以开始键入项目名称,弹出窗口中的项目列表将自动过滤 问题是,当我单击某个项目时,我希望该项目的名称显示在组合框文本区域中。相反,我得到的是一个非常简短的ItemDisplayModel.ToString(),然后是一个空字符串 ItemDisplayModel.ToString()是我从列表中选择的ItemDisplayModel类型。这是有意义的,因
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:AuctionHouseSearchFilters="clr-namespace:Codefarts.WowTracks.DataMinerWPF.Models.AuctionHouseSearchFilters"
xmlns:Models="clr-namespace:Codefarts.WowTracks.DataMinerAppCore.Models;assembly=Codefarts.WowTracks.DataMinerAppCore"
xmlns:DataMinerAppCore="clr-namespace:Codefarts.WowTracks.DataMinerAppCore;assembly=Codefarts.WowTracks.DataMinerAppCore"
xmlns:dataMinerWpf="clr-namespace:Codefarts.WowTracks.DataMinerWPF"
x:Name="userControl"
x:Class="Codefarts.WowTracks.DataMinerWPF.Controls.AuctionHouseSearchFilters.AuctionHouseItemNameControl"
mc:Ignorable="d"
d:DesignHeight="51" d:DesignWidth="283">
<UserControl.Resources>
<dataMinerWpf:UriToBitmapImageConverter x:Key="UriToImageConverter" />
<BitmapImage x:Key='defaultImage' UriSource='/Resources\118.png' />
<DataTemplate x:Key="ItemTemplate" DataType="Models:ItemDisplayModel" >
<StackPanel Orientation="Horizontal" Margin="0 5 0 5">
<Image Width="50" Height="50" Stretch="Fill" Source="{Binding IconUrl, Converter={StaticResource UriToImageConverter}, TargetNullValue={StaticResource defaultImage}}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Label Content="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<UserControl.DataContext>
<AuctionHouseSearchFilters:AuctionHouseFilterItemNameModel/>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<ComboBox x:Name="ItemList" MaxDropDownHeight="592" Grid.Row="0" ItemsSource="{Binding ItemDisplayModels}" ItemTemplate="{StaticResource ItemTemplate}" IsEditable="True" IsTextSearchEnabled="True" IsTextSearchCaseSensitive="False" Text="{Binding Value}" >
</ComboBox>
</Grid>
</UserControl>
这是我的数据模型
[Export(typeof(IAuctionHouseSearchFilter))]
public class AuctionHouseFilterItemNameModel : IAuctionHouseSearchFilter, INotifyPropertyChanged
{
private string value;
private bool connected;
private Application app;
private ItemDisplayModel[] displayItems;
private CancellationTokenSource backgroundCancel;
private bool buildingDisplayItems;
private readonly object lockObject = new object();
private ItemDisplayModel displayValue;
// private bool Handled { get; set; }
public ItemDisplayModel DisplayValue
{
get
{
return this.displayValue;
}
set
{
if (value == null)
{
return;
}
this.Value = value.Name;
this.displayValue = value;
this.OnPropertyChanged();
}
}
public string Value
{
get
{
return this.value;
}
set
{
//if (this.Handled)
//{
// return;
//}
if (value == this.value)
{
return;
}
this.value = value;
// this.Handled = true;
this.OnPropertyChanged();
var cancellationTokenSource = this.backgroundCancel;
if (cancellationTokenSource != null)
{
cancellationTokenSource.Cancel();
}
this.BuildDisplayItems();
// this.Handled = false;
}
}
public IEnumerable<AuctionDataModel> Filter(MainFilterModel model, IEnumerable<AuctionDataModel> items)
{
if (!this.connected)
{
return items;
}
// get item id from it's name
var list = this.app.ItemNames[model.SelectedRegion];
var id = list.FirstOrDefault(x => x.Name.ToLowerInvariant().Contains(this.value.Trim().ToLowerInvariant()));
return items.Where(x => id != null && x.ItemId == id.Id);
}
public IEnumerable<ItemDisplayModel> ItemDisplayModels
{
get
{
return this.displayItems;
}
}
public async void BuildDisplayItems()
{
if (this.buildingDisplayItems)
{
return;
}
if (!this.connected)
{
this.displayItems = null;
}
// return this.GetDisplayItems();
this.buildingDisplayItems = true;
this.backgroundCancel = new CancellationTokenSource();
this.OnPropertyChanged("ItemDisplayModels");
await Task.Factory.StartNew(
() =>
{
var originalItems = this.displayItems;
this.displayItems = new[] { new ItemDisplayModel() { Name = "Rebuilding list..." } };
var correctedSearchValue = this.value.Trim().ToLowerInvariant();
//lock (this.lockObject)
//{
this.displayItems = (string.IsNullOrWhiteSpace(this.value) ?
this.app.DisplayItemModels :
this.app.DisplayItemModels.Where(x => x.Name.ToLowerInvariant().Contains(correctedSearchValue))).Take(100).AsParallel().ToArray();
this.buildingDisplayItems = false;
this.OnPropertyChanged("ItemDisplayModels");
},
this.backgroundCancel.Token);
}
public string Name
{
get
{
return "Item Name";
}
}
public Type Control
{
get
{
return typeof(AuctionHouseItemNameControl);
}
}
public virtual IAuctionHouseSearchFilter Clone()
{
return new AuctionHouseFilterItemNameModel()
{
Value = this.Value
};
}
public void Connect(Application app)
{
if (this.connected)
{
return;
}
this.app = app;
this.connected = true;
}
public void Disconnect()
{
if (!this.connected)
{
return;
}
this.app = null;
this.connected = false;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class ItemDisplayModel : INotifyPropertyChanged
{
private string iconUrl;
private string region;
private string name;
private int itemId;
public int ItemId
{
get
{
return this.itemId;
}
set
{
if (value == this.itemId)
{
return;
}
this.itemId = value;
this.OnPropertyChanged();
}
}
public string Name
{
get
{
return this.name;
}
set
{
if (value == this.name)
{
return;
}
this.name = value;
this.OnPropertyChanged();
}
}
public string Region
{
get
{
return this.region;
}
set
{
if (value == this.region)
{
return;
}
this.region = value;
this.OnPropertyChanged();
}
}
public string IconUrl
{
get
{
return this.iconUrl;
}
set
{
if (value == this.iconUrl)
{
return;
}
this.iconUrl = value;
this.OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
[导出(类型(IAuctionHouseSearchFilter))]
公共类AuctionHouseFilterItemName模型:IAuctionHouseSearchFilter,INotifyPropertyChanged
{
私有字符串值;
私人楼宇联网;
私人应用程序;
私有ItemDisplayModel[]显示项;
私有取消令牌源背景取消;
私人楼宇显示项目;
私有只读对象lockObject=新对象();
私有项显示模型显示值;
//私有布尔处理{get;set;}
公共项显示模型显示值
{
得到
{
返回此.displayValue;
}
设置
{
如果(值==null)
{
返回;
}
this.Value=Value.Name;
this.displayValue=值;
this.OnPropertyChanged();
}
}
公共字符串值
{
得到
{
返回此.value;
}
设置
{
//如果(此项已处理)
//{
//返回;
//}
如果(值==此.value)
{
返回;
}
这个值=值;
//这个.Handled=true;
this.OnPropertyChanged();
var cancellationTokenSource=this.backgroundCancel;
if(cancellationTokenSource!=null)
{
cancellationTokenSource.Cancel();
}
this.BuildDisplayItems();
//这个.Handled=false;
}
}
公共IEnumerable筛选器(主筛选器模型,IEnumerable项)
{
如果(!this.connected)
{
退货项目;
}
//从其名称获取项目id
var list=this.app.ItemNames[model.SelectedRegion];
var id=list.FirstOrDefault(x=>x.Name.ToLowerInvariant().Contains(this.value.Trim().ToLowerInvariant());
返回项目。其中(x=>id!=null&&x.ItemId==id.id);
}
公共IEnumerable ItemDisplayModels
{
得到
{
返回此项。显示项目;
}
}
公共异步void BuildDisplayItems()
{
if(this.buildingDisplayItems)
{
返回;
}
如果(!this.connected)
{
this.displayItems=null;
}
//返回此.GetDisplayItems();
this.buildingDisplayItems=true;
this.backgroundCancel=新的CancellationTokenSource();
此.OnPropertyChanged(“ItemDisplayModels”);
等待Task.Factory.StartNew(
() =>
{
var originalItems=this.displayItems;
this.displayItems=new[]{new ItemDisplayModel(){Name=“Rebuilding list…”};
var correctedSearchValue=this.value.Trim().ToLowerInvariant();
//lock(this.lockObject)
//{
this.displayItems=(string.IsNullOrWhiteSpace(this.value))?
this.app.DisplayItemModels:
this.app.DisplayItemModels.Where(x=>x.Name.ToLowerInvariant().Contains(correctedSearchValue)).Take(100.aspallel().ToArray();
this.buildingDisplayItems=false;
此.OnPropertyChanged(“ItemDisplayModels”);
},
此.backgroundCancel.Token);
}
公共字符串名
{
得到
{
返回“项目名称”;
}
}
公共类型控制
{
得到
{
返回类型(AuctionHouseItemNameControl);
}
}
公共虚拟IAuctionHouseSearchFilter克隆()
{
返回新的AuctionHouseFilterIt
[Export(typeof(IAuctionHouseSearchFilter))]
public class AuctionHouseFilterItemNameModel : IAuctionHouseSearchFilter, INotifyPropertyChanged
{
private string value;
private bool connected;
private Application app;
private ItemDisplayModel[] displayItems;
private CancellationTokenSource backgroundCancel;
private bool buildingDisplayItems;
private readonly object lockObject = new object();
private ItemDisplayModel displayValue;
// private bool Handled { get; set; }
public ItemDisplayModel DisplayValue
{
get
{
return this.displayValue;
}
set
{
if (value == null)
{
return;
}
this.Value = value.Name;
this.displayValue = value;
this.OnPropertyChanged();
}
}
public string Value
{
get
{
return this.value;
}
set
{
//if (this.Handled)
//{
// return;
//}
if (value == this.value)
{
return;
}
this.value = value;
// this.Handled = true;
this.OnPropertyChanged();
var cancellationTokenSource = this.backgroundCancel;
if (cancellationTokenSource != null)
{
cancellationTokenSource.Cancel();
}
this.BuildDisplayItems();
// this.Handled = false;
}
}
public IEnumerable<AuctionDataModel> Filter(MainFilterModel model, IEnumerable<AuctionDataModel> items)
{
if (!this.connected)
{
return items;
}
// get item id from it's name
var list = this.app.ItemNames[model.SelectedRegion];
var id = list.FirstOrDefault(x => x.Name.ToLowerInvariant().Contains(this.value.Trim().ToLowerInvariant()));
return items.Where(x => id != null && x.ItemId == id.Id);
}
public IEnumerable<ItemDisplayModel> ItemDisplayModels
{
get
{
return this.displayItems;
}
}
public async void BuildDisplayItems()
{
if (this.buildingDisplayItems)
{
return;
}
if (!this.connected)
{
this.displayItems = null;
}
// return this.GetDisplayItems();
this.buildingDisplayItems = true;
this.backgroundCancel = new CancellationTokenSource();
this.OnPropertyChanged("ItemDisplayModels");
await Task.Factory.StartNew(
() =>
{
var originalItems = this.displayItems;
this.displayItems = new[] { new ItemDisplayModel() { Name = "Rebuilding list..." } };
var correctedSearchValue = this.value.Trim().ToLowerInvariant();
//lock (this.lockObject)
//{
this.displayItems = (string.IsNullOrWhiteSpace(this.value) ?
this.app.DisplayItemModels :
this.app.DisplayItemModels.Where(x => x.Name.ToLowerInvariant().Contains(correctedSearchValue))).Take(100).AsParallel().ToArray();
this.buildingDisplayItems = false;
this.OnPropertyChanged("ItemDisplayModels");
},
this.backgroundCancel.Token);
}
public string Name
{
get
{
return "Item Name";
}
}
public Type Control
{
get
{
return typeof(AuctionHouseItemNameControl);
}
}
public virtual IAuctionHouseSearchFilter Clone()
{
return new AuctionHouseFilterItemNameModel()
{
Value = this.Value
};
}
public void Connect(Application app)
{
if (this.connected)
{
return;
}
this.app = app;
this.connected = true;
}
public void Disconnect()
{
if (!this.connected)
{
return;
}
this.app = null;
this.connected = false;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class ItemDisplayModel : INotifyPropertyChanged
{
private string iconUrl;
private string region;
private string name;
private int itemId;
public int ItemId
{
get
{
return this.itemId;
}
set
{
if (value == this.itemId)
{
return;
}
this.itemId = value;
this.OnPropertyChanged();
}
}
public string Name
{
get
{
return this.name;
}
set
{
if (value == this.name)
{
return;
}
this.name = value;
this.OnPropertyChanged();
}
}
public string Region
{
get
{
return this.region;
}
set
{
if (value == this.region)
{
return;
}
this.region = value;
this.OnPropertyChanged();
}
}
public string IconUrl
{
get
{
return this.iconUrl;
}
set
{
if (value == this.iconUrl)
{
return;
}
this.iconUrl = value;
this.OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
<ComboBox x:Name="ItemList"
Grid.Row="0"
IsEditable="True"
IsTextSearchCaseSensitive="False"
IsTextSearchEnabled="True"
ItemTemplate="{StaticResource ItemTemplate}"
ItemsSource="{Binding ItemDisplayModels}"
MaxDropDownHeight="592"
TextSearch.TextPath="Name" />