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.

WPF - MVVM: ComboBox-Wert nach SelectionChanged

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.
Schreibe einen Kommentar