【发布时间】:2015-11-04 09:49:06
【问题描述】:
编辑2: 我正在做一些项目,我的 ComboBox 包含一个可编辑元素的列表。在选择其中一个元素后,这些元素是可编辑的。我想要的是,当我取消选择它时,所选元素的编辑属性会被记住,并且 ComboBox 下拉列表会使用新元素的描述进行更新。下面是这个例子的样子:
现在切换后会记住更改,但下拉列表仍然包含旧名称,并且不会自动更新:
这是代码。
MainWindow.xaml
<Window x:Class="MVVMEditComboBoxItemsSample.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:MVVMEditComboBoxItemsSample"
mc:Ignorable="d"
Title="MVVM ComboBox edit sample" Height="372.52" Width="415.214">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50*"></RowDefinition>
<RowDefinition Height="81*"/>
<RowDefinition Height="26*"/>
<RowDefinition Height="45*"/>
<RowDefinition Height="26*"/>
<RowDefinition Height="44*"/>
</Grid.RowDefinitions>
<ComboBox Grid.Row="0" Margin="10" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" ItemsSource="{Binding Path=Things}" SelectedItem="{Binding Path=SelectedThing, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></ComboBox>
<StackPanel Grid.Row="1" Margin="10">
<Button Command="{Binding Path=AddCommand}">Add Item</Button>
<Button Command="{Binding Path=CloneCommand}">Clone Item</Button>
<Button Command="{Binding Path=DeleteCommand}">Delete Item</Button>
</StackPanel>
<Label Grid.Row="2" Margin="0" >Name</Label>
<TextBox Grid.Row="3" HorizontalAlignment="Stretch" Margin="10" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Text="{Binding Path=Name}"/>
<Label Grid.Row="4" Margin="0" >Price</Label>
<TextBox Grid.Row="5" HorizontalAlignment="Stretch" Margin="10" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" Text="{Binding Path=Price}"/>
</Grid>
</Window>
MainViewModel.cs
using MVVMEditComboBoxItemsSample.MockModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace MVVMEditComboBoxItemsSample
{
class MainViewModel : ViewModelBase
{
private ObservableCollection<Thing> things;
private Thing selectedThing;
private ICommand addCommand;
private ICommand cloneCommand;
private ICommand deleteCommand;
public MainViewModel()
{
Things = new ObservableCollection<Thing>(ThingDataManager.Instance.GetThings());
SelectedThing = Things.FirstOrDefault();
}
public ObservableCollection<Thing> Things
{
get
{
return things;
}
set
{
things = value;
OnPropertyChanged(nameof(Things));
}
}
public Thing SelectedThing
{
get
{
return selectedThing;
}
set
{
selectedThing = value;
OnPropertyChanged(nameof(SelectedThing));
OnPropertyChanged(nameof(Name));
OnPropertyChanged(nameof(Price));
//OnPropertyChanged(nameof(Things));
}
}
public string Name
{
get
{
if (SelectedThing != null)
{
return SelectedThing.Name;
}
return null;
}
set
{
SelectedThing.Name = value;
OnPropertyChanged(nameof(Name));
}
}
public string Price
{
get
{
if (SelectedThing != null)
{
return SelectedThing.Price;
}
return null;
}
set
{
SelectedThing.Price = value;
OnPropertyChanged(nameof(Price));
}
}
public ICommand AddCommand
{
get
{
if(addCommand==null)
{
addCommand = new CommandBase(i => AddItem(), null);
}
return addCommand;
}
}
public ICommand CloneCommand
{
get
{
if(cloneCommand==null)
{
cloneCommand = new CommandBase(i => CloneItem(), null);
}
return cloneCommand;
}
}
public ICommand DeleteCommand
{
get
{
if(deleteCommand==null)
{
deleteCommand = new CommandBase(i => DeleteItem(), null);
}
return deleteCommand;
}
}
public void AddItem()
{
Thing newThing = new Thing();
Things.Add(newThing);
SelectedThing = newThing;
}
public void CloneItem()
{
Thing clonedThing = new Thing();
clonedThing.Name = SelectedThing.Name;
clonedThing.Price = SelectedThing.Price;
Things.Add(clonedThing);
SelectedThing = clonedThing;
}
public void DeleteItem()
{
Thing tempThing = new Thing();
tempThing = SelectedThing;
if (Things.IndexOf(SelectedThing) != 0)
{
SelectedThing = Things.FirstOrDefault();
}
else if (Things.Count==1)
{
SelectedThing = null;
}
else
{
SelectedThing = Things[1];
}
Things.Remove(tempThing);
}
}
}
Thing.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVVMEditComboBoxItemsSample.MockModel
{
class Thing
{
public string Name { get; set; }
public string Price { get; set; }
public override string ToString()
{
return Name;
}
}
}
ThingDataManager
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MVVMEditComboBoxItemsSample.MockModel
{
class ThingDataManager
{
private static ThingDataManager _instance;
public static ThingDataManager Instance
{
get
{
if (_instance==null)
{
_instance = new ThingDataManager();
}
return _instance;
}
}
private ThingDataManager()
{
}
public List<Thing> GetThings()
{
List<Thing> things = new List<Thing>();
things.Add(new Thing { Name = "Book", Price = "12$" });
things.Add(new Thing { Name = "Hammer", Price = "2$" });
things.Add(new Thing { Name = "Fridge", Price = "1200$" });
return things;
}
}
}
我希望 ViewModelBase 和 CommandBase 等其余部分具有足够的自我描述性:)。
知道为什么我的下拉列表没有更新为当前的事物名称吗?
编辑: 好的,我在github上传了简化版:
github.com/piotr-napadlek/MVVMEditComboBoxItemsSample
仍然无法正常工作的是 ComboBox 下拉菜单的项目在更改名称文本框的值时不会更改。另外,请让我知道此示例中的一般方法是否正确。干杯。
【问题讨论】: