WPF - MVVM: ComboBox-Wert nach SelectionChanged
Ich bin neu in C# und MVVM, und ich habe den ganzen Tag versucht, um den Wert einer ComboBox
zu meinem ViewModel auf SelectionChanged
. Ich habe es geschafft, um es herauszufinden, entweder CallMethodAction
oder InvokeCommandAction
mit den Ressourcen:
System.Windows.Interactivity.dll
Microsoft.Expression.Interactions.dll
Mein problem ist, dass diese beiden Methoden liefern den Wert der ComboBox
bevor er sich verändert hat. Könnte jemand erklären, wie man den Wert nach das ändern?
Verbrachte ich Stunden mit der Suche durch SO und Google für eine Lösung, so Frage ich mich, ob andere zu. Jede Beratung wird geschätzt!
Mein code ist unten:
MainWindow.xaml
<Window x:Class="SelectionChange.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:si="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
xmlns:vm="clr-namespace:SelectionChange"
Title="MainWindow" Width="300" Height="300">
<Window.DataContext>
<vm:ViewModel />
</Window.DataContext>
<Grid>
<ComboBox Name="SelectBox" VerticalAlignment="Top" SelectedIndex="0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<si:CallMethodAction MethodName="SelectionChanged" TargetObject="{Binding}" />
<!--<i:InvokeCommandAction Command="{Binding SelectionChangedCommand}" CommandParameter="{Binding ElementName=SelectBox, Path=Text}" />-->
</i:EventTrigger>
</i:Interaction.Triggers>
<ComboBoxItem Content="Item 1" />
<ComboBoxItem Content="Item 2" />
<ComboBoxItem Content="Item 3" />
</ComboBox>
</Grid>
</Window>
ViewModel.cs
namespace SelectionChange
{
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
public class ViewModel
{
public ViewModel()
{
SelectionChangedCommand = new SelectionChangedCommand();
}
public ICommand SelectionChangedCommand
{
get;
set;
}
public void SelectionChanged(object sender, EventArgs e)
{
ComboBox SelectBox = (ComboBox)sender;
MessageBox.Show("Called SelectionChanged: " + SelectBox.Text);
}
}
}
SelectionChangedCommand.cs
namespace SelectionChange
{
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
public class SelectionChangedCommand : ICommand
{
public SelectionChangedCommand()
{
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
MessageBox.Show("Executed SelectionChangedCommand: " + parameter);
}
}
}
Edit: Meine Lösung
Es stellt sich heraus, dass ich nicht verstehen Binding
gut genug, und stattdessen wurde versucht, etwas umzusetzen, einfach in einer ziemlich komplizierten Art und Weise! Anstelle der Verwendung von Abhängigkeiten, habe ich jetzt erreicht, was ich brauchte, mit regelmäßigen Bindungen. Als Beispiel, ich habe gebunden TextBox
zu den SelectedIndex
des ComboBox
, die aktualisiert wird mit INotifyPropertyChanged
.
MainWindow.xaml
<Window x:Class="SelectionChange.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SelectionChange"
Title="MainWindow" Width="300" Height="300">
<Window.DataContext>
<vm:ViewModel />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ComboBox SelectedItem="{Binding SelectedItem}" SelectedIndex="0" Grid.Column="0" VerticalAlignment="Top">
<ComboBoxItem Content="Item 1" />
<ComboBoxItem Content="Item 2" />
<ComboBoxItem Content="Item 3" />
</ComboBox>
<!-- TextBox to display the ComboBox's SelectedIndex -->
<TextBox Text="{Binding SelectedIndex}" Grid.Column="1" VerticalAlignment="Top" />
</Grid>
</Window>
ViewModel.cs
namespace SelectionChange
{
using System;
using System.ComponentModel;
using System.Windows.Controls;
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
}
//Property to store /retrieve ComboBox's SelectedIndex
private int _SelectedIndex;
public int SelectedIndex { get; set; }
//Property to bind to ComboBox's SelectedItem
private ComboBoxItem _SelectedItem;
public ComboBoxItem SelectedItem
{
get { return _SelectedItem; }
set
{
_SelectedItem = value;
//SelectedItem's Content
string Content = (string)value.Content;
//SelectedItem's parent (i.e. the ComboBox)
ComboBox SelectBox = (ComboBox)value.Parent;
//ComboBox's SelectedIndex
int Index = SelectBox.SelectedIndex;
//Store the SelectedIndex in the property
SelectedIndex = Index;
//Raise PropertyChanged with the name of the stored property
RaisePropertyChanged("SelectedIndex");
}
}
//INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
}
}
}
- Wenn ich verstehe, was Sie versuchen zu tun, ich denke, das wird helfen, stackoverflow.com/questions/4765362/mvvm-combobox-binding
- Ich werde einfach eine Idee für Sie. Wie über binden Sie die SelectedItems-Eigenschaft an eine Eigenschaft in der ViewModel mit verbindlichen Modus TwoWay? Keine Notwendigkeit zu hören, um SelectionChanged-Ereignis oder Befehle erstellen. Wenn Sie die SelectedItems-Wert verändert wird bekommst du eine Mitteilung im inneren der setter von Ihrer Immobilie im ViewModel. Probieren Sie es aus.
- <ComboBox ItemsSource="{Binding Path=PropertyWhichHasList, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" SelectedItem="{Binding PropertyWhichHasSelectedItem}" </ComboBox>. Probieren Sie etwas wie dieses .
- Vielen Dank an alle 3 Vorschläge! Sie haben mir geholfen, eine Lösung zu finden.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Warum es nicht der einfachere Weg
In der ViewModel deklarieren Sie die combo-box-Elemente und Verwendung einer Eigenschaft "Source", um Sie wieder in die Ansicht
Dann definieren Sie eine Eigenschaft, die hält das ausgewählte Element
Vergessen Sie auch nicht zu implementieren, die INotifyPropertyChanged-Schnittstelle während der Einstellung der _source
Wenn Sie nur wollen, um benachrichtigt zu werden, wenn Ihre aktuelle Element ändert, warum nicht Werkzeuge, die bereits Teil der WPF-statt alle diese Abhängigkeiten.
Zunächst die zugrunde liegende Blick auf Ihre Sammlung und Nutzung der CurrentChanged-event auf Sie.
In xaml Sie einfach binden Sie Ihre Sammlung und legen Sie
IsSynchronizedWithCurrentItem
zu wahren.