Estas son todas buenas sugerencias, pero si Estabas tú, yo haría esto en tu modelo de vista. Dentro de su modelo de vista, puede crear un comando de retransmisión que luego puede vincular al evento de clic en su plantilla de elemento. Para determinar si se seleccionó el mismo elemento, puede almacenar una referencia al elemento seleccionado en su modelo de vista. Me gusta usar MVVM Light para manejar el enlace. Esto hace que su proyecto sea mucho más fácil de modificar en el futuro, y le permite configurar el enlace en Blend.
Cuando todo está dicho y hecho, su XAML se verá como lo sugirió Sergey. Evitaría usar el código en tu vista. Voy a evitar escribir código en esta respuesta, porque hay un montón de ejemplos por ahí.
Aquí está uno: How to use RelayCommand with the MVVM Light framework
Si necesita un ejemplo, por favor, comentar, y voy a agregar uno.
~ Saludos
dije que no iba a hacer un ejemplo, pero lo estoy. Aqui tienes.
1) En su proyecto, agregue solo las bibliotecas de luces MVVM.
2) Cree una clase para su vista. En general, tiene un modelo de vista para cada vista (ver: MainWindow.xaml & & viewModel: MainWindowViewModel.cs)
3) Aquí está el código para el modelo de vista muy, muy, muy básico:
Todo espacio de nombre incluido (si es que aparecen aquí, estoy suponiendo que ya ha añadido la referencia a ellos MVVM Light. está en 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;
Ahora añadir una clase pública básica:
/// <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;
}
}
Ahora crear su modelo de vista:
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); }
}
}
En su viewmodel, agregue un comando de retransmisión. Tenga en cuenta que hice este asincrónico y lo hice pasar un parámetro.
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);
}
En el código subyacente para usted ver, crear una propiedad para usted modelo de vista y establecer el DataContext para su visión para el modelo de vista (tenga en cuenta, hay otras maneras de hacer esto, pero estoy tratando de hacer esto un ejemplo sencillo.)
public partial class MainWindow : Window
{
public MainWindowViewModel MyViewModel { get; set; }
public MainWindow()
{
InitializeComponent();
MyViewModel = new MainWindowViewModel();
this.DataContext = MyViewModel;
}
}
En el XAML, es necesario agregar algunos espacios de nombres a la parte superior de su código
<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">
añadí "i" y "Custom".
Aquí es el ListView:
<ListView
Grid.Row="0"
Grid.Column="0"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding ModelsCollection}"
ItemTemplate="{DynamicResource BasicModelDataTemplate}">
</ListView>
Aquí es ItemTemplate para el ListView:
<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>
ejecutar su aplicación, y echa un vistazo a la ventana de salida. Puede usar un convertidor para manejar el estilo del elemento seleccionado.
Esto puede parecer muy complicado, pero hace la vida mucho más fácil en el futuro cuando necesita separar su vista de su ViewModel (por ejemplo, desarrollar un ViewModel para múltiples plataformas). Además, hace que trabajar en Blend 10x sea más fácil. Una vez que desarrolle su ViewModel, puede entregarlo a un diseñador que puede hacer que se vea muy artístico :). MVVM Light agrega algunas funcionalidades para que Blend reconozca su ViewModel. En su mayor parte, puede hacer prácticamente todo lo que desee en ViewModel para afectar la vista.
Si alguien lee esto, espero que encuentre esto útil. Si tiene preguntas, hágamelo saber. Usé MVVM Light en este ejemplo, pero podrías hacer esto sin MVVM Light.
~ Saludos
En realidad, se puede establecer el controlador directamente en el 'ListView', no hay necesidad de un EventSetter. –