请原谅我,因为我仍然是MVVM和WPF c#的新手(以及一般的编程)。我读了很多,感到不知所措,只是需要一些指导来克服这个问题。我将尝试将程序简化为如下所示的简单示例:
超市有以下商品:
苹果- 桃 芒果香蕉
- 卫生纸 Iphone>
我有几个客户(客户对象)。每个客户对象都包含他的项目的集合。items对象包含名称和数量。例如:
顾客X的购物车中有以下商品项 量
- 苹果 1
- 香蕉 2
- 桃子 3
所以我的简化应用程序如下。我打开应用程序,它有一个列表视图与我当前的客户列表。我按下一个客户并修改它。这将打开一个新窗口。该窗口包含一个数据网格。第一列是他购物车中的商品(组合框列),第二列是带有数量的文本列。
我希望能够修改项目和数量。我的问题是组合框栏;我希望它是可编辑的,并允许我根据该单元格中的当前输入过滤下拉列表。例如,如果我按下它,我不输入任何东西,它将有可用项目的完整列表。如果我按下"它将进一步过滤所有以"a"开头的单词。我还想实现验证,以便组合框列不允许任何重复(我可能能够单独解决这个问题)。
这里是一些代码,我已经实现了这个例子(MVVM结构)。这段代码跳过第一个窗口,直接进入带有数据网格的窗口<<strong>我的模型/strong>Customer.cs
public class Customer:INotifyPropertyChanged
{
private string name;
public ObservableCollection<Item> Items { get; set; }
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public Customer()
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyRaised(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
}
Item.cs
public class Item : INotifyPropertyChanged
{
private string name;
private double quantity;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public double Quantity
{
get
{
return quantity;
}
set
{
quantity = value;
}
}
public Item()
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyRaised(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
}
ViewModel
public class MainWindowViewModel
{
public Customer ObjCustomer
{
get; set;
}
private ObservableCollection<object> itemslist;
public ObservableCollection<object> ItemsList
{
get { return itemslist; }
set { itemslist = value; }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyRaised(string propertyname)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
}
}
public MainWindowViewModel()
{
ObjCustomer = new Customer();
ObjCustomer.Items = LoadCustomerItems();
ItemsList = LoadAvailableItems();
}
private ObservableCollection<object> LoadAvailableItems()
{
ObservableCollection<object> combosAndLoadCasesList = new ObservableCollection<object>();
combosAndLoadCasesList.Add(new Item() { Name = "Apple" });
combosAndLoadCasesList.Add(new Item() { Name = "Peach" });
combosAndLoadCasesList.Add(new Item() { Name = "Mango" });
combosAndLoadCasesList.Add(new Item() { Name = "Banana" });
combosAndLoadCasesList.Add(new Item() { Name = "Toilet paper" });
combosAndLoadCasesList.Add(new Item() { Name = "Iphone" });
combosAndLoadCasesList.Add(new Item() { Name = "Water" });
return combosAndLoadCasesList;
}
private ObservableCollection<Item> LoadCustomerItems()
{
ObservableCollection<Item> ItemsForCustomer = new ObservableCollection<Item>();
ItemsForCustomer.Add(new Item() { Name = "Apple", Quantity = 1 });
ItemsForCustomer.Add(new Item() { Name = "Banana", Quantity = 2 });
ItemsForCustomer.Add(new Item() { Name = "Peaches", Quantity = 3 });
return ItemsForCustomer;
}
}
My window xaml
<Window x:Class="ComboBoxDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ComboBoxDemo"
xmlns:Syncfusion="http://schemas.syncfusion.com/wpf"
xmlns:i = "http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
Title="MainWindow" Height="500" Width="500">
<Window.Resources>
<local:MainWindowViewModel x:Key="viewModel"/>
</Window.Resources>
<Grid>
<DataGrid HorizontalAlignment="Left"
Height="374"
Margin="37,31,0,64"
VerticalAlignment="Center"
Width="391"
ItemsSource="{Binding ObjCustomer.Items,Source={StaticResource viewModel}}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Item"
ItemsSource="{Binding ItemsList,Source={StaticResource viewModel}}"
TextBinding="{Binding BindingGroupName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="Name"/>
<DataGridTextColumn Header="Quantity"
Binding="{Binding Quantity, Mode=TwoWay}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
我尝试过一些WPF框架,比如Syncfusion。你们会推荐这些功能吗?还是我应该坚持使用标准的WPF功能?如果有任何提示,请告诉我!
这里有一个SO页面,上面有一些关于过滤/自动完成组合框问题的答案:
我注意到你的set属性都缺少对OnPropertyRaised
的调用,这将使你的绑定不工作-特别是数量一个。请查看https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/how-to-implement-property-change-notification以了解该如何工作。
我玩过一些WPF框架,比如Syncfusion。你们会推荐这些功能吗?还是我应该坚持使用标准的WPF功能?如果有任何提示,请告诉我!
我个人使用Devexpress,并且非常喜欢它,但是它们也需要一些时间来适应和学习。而且它们也不便宜。
我也倾向于使用Prism的MVVM而不是普通的WPF,因为我得到了很多东西开箱,如导航,自动链接视图到ViewModels和全局事件聚合器传递事件。
你可能会发现每个人对于是否使用这些库都有不同的看法。我发现它们很有帮助,让我更有效率,所以我个人推荐使用它们。
PS:只是想补充一下,如果你使用像devexpress这样的库,你将主要得到像下拉自动完成这样的控件已经内置在这个…