这些都是很好的建议,但如果我是你,我会在你的视图模型中完成。在你的视图模型中,你可以创建一个中继命令,然后将其绑定到你的项目模板中的点击事件。为了确定是否选择了相同的项目,你可以在你的视图模型中存储对所选项目的引用。我喜欢使用MVVM Light来处理绑定。这使得你的项目在未来更容易修改,并允许你在Blend中设置绑定。
最终,你的XAML看起来会像Sergey建议的那样。我建议避免在你的视图中使用代码。我不会在这个答案中写代码,因为有很多例子可以参考。
这里是一个例子:
如何在MVVM Light框架中使用RelayCommand
如果你需要一个例子,请评论,我会添加一个。
~干杯
In your project, add MVVM Light Libraries Only.
创建一个视图类。一般来说,每个视图都有一个视图模型(例如:视图为MainWindow.xaml,视图模型为MainWindowViewModel.cs)。
以下是非常基础的视图模型代码:
所有包含的命名空间(如果它们出现在这里,我假设您已经将它们添加到引用中。MVVM Light可以在Nuget中找到)。
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
现在添加一个基本的公共类:
public class BasicModel
{
public string Id { get; set; }
public string Text { get; set; }
public BasicModel(string text)
{
this.Id = Guid.NewGuid().ToString();
this.Text = text;
}
}
现在创建你的视图模型:
public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel()
{
ModelsCollection = new ObservableCollection<BasicModel>(new List<BasicModel>() {
new BasicModel("Model one")
, new BasicModel("Model two")
, new BasicModel("Model three")
});
}
private BasicModel _selectedBasicModel;
public BasicModel SelectedBasicModel
{
get { return _selectedBasicModel; }
set { Set(() => SelectedBasicModel, ref _selectedBasicModel, value); }
}
private ObservableCollection<BasicModel> _modelsCollection;
public ObservableCollection<BasicModel> ModelsCollection
{
get { return _modelsCollection; }
set { Set(() => ModelsCollection, ref _modelsCollection, value); }
}
}
在您的视图模型中添加一个RelayCommand。请注意,我将其设置为异步,并传递了一个参数。
private RelayCommand<string> _selectItemRelayCommand;
public RelayCommand<string> SelectItemRelayCommand
{
get
{
if (_selectItemRelayCommand == null)
{
_selectItemRelayCommand = new RelayCommand<string>(async (id) =>
{
await selectItem(id);
});
}
return _selectItemRelayCommand;
}
set { _selectItemRelayCommand = value; }
}
private async Task<int> selectItem(string id)
{
this.SelectedBasicModel = ModelsCollection.FirstOrDefault(x => x.Id == id);
Console.WriteLine(String.Concat("You just clicked:", SelectedBasicModel.Text));
return await Task.FromResult(1);
}
在您的视图代码后台中,为您的视图创建一个视图模型属性,并将您的视图的数据上下文设置为该视图模型(请注意,还有其他方法可以实现此目的,但我正在尝试让这个例子变得简单明了)。
public partial class MainWindow : Window
{
public MainWindowViewModel MyViewModel { get; set; }
public MainWindow()
{
InitializeComponent();
MyViewModel = new MainWindowViewModel();
this.DataContext = MyViewModel;
}
}
在您的 XAML 中,您需要在代码顶部添加一些命名空间。
<Window x:Class="Basic_Binding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:Custom="clr-namespace:GalaSoft.MvvmLight;assembly=GalaSoft.MvvmLight"
Title="MainWindow" Height="350" Width="525">
我添加了“i”和“Custom”。
这是ListView:
<ListView
Grid.Row="0"
Grid.Column="0"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding ModelsCollection}"
ItemTemplate="{DynamicResource BasicModelDataTemplate}">
</ListView>
这是 ListView 的 ItemTemplate:
<DataTemplate x:Key="BasicModelDataTemplate">
<Grid>
<TextBlock Text="">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction
Command="}}"
CommandParameter="">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</Grid>
</DataTemplate>
运行你的应用程序,查看输出窗口。你可以使用转换器来处理所选项目的样式。这似乎非常复杂,但是当你需要将视图与ViewModel分离(例如为多个平台开发ViewModel)时,它会让生活变得更加容易。此外,在Blend中工作会更加容易。一旦你开发了ViewModel,你就可以将其交给设计师,让他们把它变得非常艺术化 :)。MVVM Light添加了一些功能,使Blend能够识别你的ViewModel。在大多数情况下,你可以在ViewModel中做任何想做的事情来影响视图。如果有人阅读这篇文章,我希望你会觉得有帮助。如果你有问题,请让我知道。我在这个示例中使用了MVVM Light,但你也可以不使用它。