これらはすべて素晴らしい提案ですが、私があなたなら、ビューモデルでこれを行います。ビューモデル内で、アイテムテンプレートのクリックイベントにバインドできるリレーコマンドを作成できます。同じアイテムが選択されたかどうかを判断するために、選択したアイテムへの参照をビューモデルに保存できます。バインディングを処理するためにMVVMLightを使用するのが好きです。これにより、プロジェクトを将来変更するのがはるかに簡単になり、Blendでバインディングを設定できるようになります。
すべてが語られて完了すると、XAMLはSergeyが提案したもののようになります。私はあなたの見解でコードビハインドを使用することを避けます。そこにはたくさんの例があるので、この回答でコードを書くことは避けます。
これが1つです:
MVVMLightフレームワークでRelayCommandを使用する方法
例が必要な場合はコメントしてください。追加します。
〜乾杯
私は例をするつもりはないと言いましたが、私はそうです。どうぞ。
プロジェクトに、MVVMライトライブラリのみを追加します。
ビューのクラスを作成します。一般的に、ビューごとにビューモデルがあります(ビュー:MainWindow.xaml && viewModel:MainWindowViewModel.cs)
非常に、非常に、非常に基本的なビューモデルのコードは次のとおりです。
含まれているすべての名前空間(ここに表示されている場合は、既にそれらへの参照を追加していると想定しています。MVVMLightは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;
次に、基本的なパブリッククラスを追加します。
/// <summary>
/// Very basic model for example
/// </summary>
public class BasicModel
{
public string Id { get; set; }
public string Text { get; set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="text"></param>
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;
/// <summary>
/// Stores the selected mode.
/// </summary>
/// <remarks>This is just an example, may be different.</remarks>
public BasicModel SelectedBasicModel
{
get { return _selectedBasicModel; }
set { Set(() => SelectedBasicModel, ref _selectedBasicModel, value); }
}
private ObservableCollection<BasicModel> _modelsCollection;
/// <summary>
/// List to bind to
/// </summary>
public ObservableCollection<BasicModel> ModelsCollection
{
get { return _modelsCollection; }
set { Set(() => ModelsCollection, ref _modelsCollection, value); }
}
}
ビューモデルに、relayコマンドを追加します。これを非同期にして、パラメーターを渡してもらうことに注意してください。
private RelayCommand<string> _selectItemRelayCommand;
/// <summary>
/// Relay command associated with the selection of an item in the observablecollection
/// </summary>
public RelayCommand<string> SelectItemRelayCommand
{
get
{
if (_selectItemRelayCommand == null)
{
_selectItemRelayCommand = new RelayCommand<string>(async (id) =>
{
await selectItem(id);
});
}
return _selectItemRelayCommand;
}
set { _selectItemRelayCommand = value; }
}
/// <summary>
/// I went with async in case you sub is a long task, and you don't want to lock you UI
/// </summary>
/// <returns></returns>
private async Task<int> selectItem(string id)
{
this.SelectedBasicModel = ModelsCollection.FirstOrDefault(x => x.Id == id);
Console.WriteLine(String.Concat("You just clicked:", SelectedBasicModel.Text));
//Do async work
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="{Binding Text}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction
Command="{Binding DataContext.SelectItemRelayCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ItemsControl}}}"
CommandParameter="{Binding Id}">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
</Grid>
</DataTemplate>
アプリケーションを実行し、出力ウィンドウを確認します。コンバーターを使用して、選択したアイテムのスタイリングを処理できます。
これは非常に複雑に見えるかもしれませんが、ビューをViewModelから分離する必要がある場合(たとえば、複数のプラットフォーム用のViewModelを開発する場合)、将来の作業がはるかに簡単になります。さらに、Blend10xでの作業が簡単になります。ViewModelを開発したら、それを非常に芸術的に見せることができるデザイナーに渡すことができます:)。MVVM Lightは、BlendにViewModelを認識させるためのいくつかの機能を追加します。ほとんどの場合、ViewModelでビューに影響を与えるために必要なことはほぼすべて実行できます。
誰かがこれを読んだら、これがお役に立てば幸いです。ご不明な点がございましたら、お気軽にお問い合わせください。この例ではMVVMLightを使用しましたが、MVVMLightがなくてもこれを行うことができます。