WPF - MVVM:以后的SelectionChanged组合框值 [英] WPF - MVVM: ComboBox value after SelectionChanged

查看:272
本文介绍了WPF - MVVM:以后的SelectionChanged组合框值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新的C#和MVVM,我已经花了一整天试图让的SelectionChanged一个组合框我的视图模型的价值。我设法用弄明白要么 CallMethodAction InvokeCommandAction 与资源:


  • System.Windows.Interactivity.dll

  • Microsoft.Ex pression.Interactions.dll

我的问题是,这两种方法返回之前,它已经改变了组合框的值。任何人都可以解释如何获取值的之后的变化?

我花了几个小时寻遍SO和谷歌的解决方案,所以我不知道如果其他人也有同感。任何意见将是AP preciated!

我的code是如下:

MainWindow.xaml

 <窗​​口x:类=SelectionChange.MainWindow
        的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
        的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
        的xmlns:I =CLR的命名空间:System.Windows.Interactivity;装配= System.Windows.Interactivity
        xmlns:si=\"clr-namespace:Microsoft.Ex$p$pssion.Interactivity.Core;assembly=Microsoft.Ex$p$pssion.Interactions\"
        的xmlns:VM =CLR的命名空间:SelectionChange
        标题=主窗口WIDTH =300HEIGHT =300>
    < Window.DataContext>
        < VM:视图模型/>
    < /Window.DataContext>
    <网格和GT;
        <组合框名称=选择框VerticalAlignment =顶部的SelectedIndex =0>
            < I:Interaction.Triggers>
                < I:的EventTrigger事件名称=的SelectionChanged>
                    < SI:CallMethodAction方法名=的SelectionChangedTargetObject ={结合}/>
                    !< - < I:InvokeCommandAction命令={结合SelectionChangedCommand}CommandParameter ={绑定的ElementName =选择框,路径=文本}/> - >
                < /我:&的EventTrigger GT;
            < /我:Interaction.Triggers>
            < ComboBoxItem CONTENT =项目1/>
            < ComboBoxItem CONTENT =项目2/>
            < ComboBoxItem CONTENT =项目3/>
        < /组合框>
    < /网格和GT;
< /窗GT;

ViewModel.cs

 命名空间SelectionChange
{
    使用系统;
    使用System.Windows;
    使用System.Windows.Controls的;
    使用System.Windows.Input;    公共类视图模型
    {
        公共视图模型()
        {
            SelectionChangedCommand =新SelectionChangedCommand();
        }        公众的ICommand SelectionChangedCommand
        {
            得到;
            组;
        }        公共无效的SelectionChanged(对象发件人,EventArgs的发送)
        {
            组合框选择框=(组合框)发送;
            的MessageBox.show(叫的SelectionChanged:+ SelectBox.Text);
        }
    }
}

SelectionChangedCommand.cs

 命名空间SelectionChange
{
    使用系统;
    使用System.Windows;
    使用System.Windows.Controls的;
    使用System.Windows.Input;    公共类SelectionChangedCommand:ICommand的
    {
        公共SelectionChangedCommand()
        {
        }        公共事件的EventHandler CanExecuteChanged;        公共BOOL CanExecute(对象参数)
        {
            返回true;
        }        公共无效执行(对象参数)
        {
            的MessageBox.show(执行的SelectionChangedCommand:+参数);
        }
    }
}

结果搜索结果
修改:我的解决方案

原来我不明白绑定不够好,而是试图实现东西在一个相当复杂的方式简单!而不是使用依赖,现在我已经实现了我所需要使用普通绑定。举个例子,我约束的文本框的SelectedIndex 组合框,这将会采用更新的 INotifyPropertyChanged的

MainWindow.xaml

 <窗​​口x:类=SelectionChange.MainWindow
        的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
        的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
        的xmlns:VM =CLR的命名空间:SelectionChange
        标题=主窗口WIDTH =300HEIGHT =300>
    < Window.DataContext>
        < VM:视图模型/>
    < /Window.DataContext>
    <网格和GT;
        < Grid.ColumnDefinitions>
            < ColumnDefinition WIDTH =自动/>
            &所述; ColumnDefinition宽度=*/>
        < /Grid.ColumnDefinitions>        <组合框的SelectedItem ={结合的SelectedItem}的SelectedIndex =0Grid.Column =0VerticalAlignment =评出的>
            < ComboBoxItem CONTENT =项目1/>
            < ComboBoxItem CONTENT =项目2/>
            < ComboBoxItem CONTENT =项目3/>
        < /组合框>        <! - 文本框来显示组合框的selectedIndex - >
        <文本框的文本={结合的SelectedIndex}Grid.Column =1VerticalAlignment =顶部/>
    < /网格和GT;
< /窗GT;

ViewModel.cs

 命名空间SelectionChange
{
    使用系统;
    使用System.ComponentModel;
    使用System.Windows.Controls的;    公共类视图模型:INotifyPropertyChanged的
    {
        公共视图模型()
        {
        }        //属性来存储/检索组合框的selectedIndex
        私人诠释_SelectedIndex;
        公众诠释的SelectedIndex {搞定;组; }        //属性绑定到组合框的的SelectedItem
        私人ComboBoxItem _SelectedItem;
        公共ComboBoxItem的SelectedItem
        {
            {返回_SelectedItem; }
            组
            {
                _SelectedItem =价值;                //的SelectedItem的内容
                字符串内容=(字符串)value.Content;                //的SelectedItem的母公司(即组合框)
                组合框选择框=(组合框)value.Parent;                //组合框的selectedIndex
                INT指数= SelectBox.SelectedIndex;                //存放的SelectedIndex在属性
                的SelectedIndex =指数;                //提高的PropertyChanged与存储的属性的名称
                RaisePropertyChanged(的SelectedIndex);
            }
        }        // INotifyPropertyChanged的
        公共事件PropertyChangedEventHandler的PropertyChanged;
        私人无效RaisePropertyChanged(字符串属性名)
        {
            如果(的PropertyChanged!= NULL)
                的PropertyChanged(这一点,新PropertyChangedEventArgs(属性名));
        }
    }
}


解决方案

为什么不这样做的简单的方法

 <组合框了maxHeight =25
          的ItemsSource ={绑定源}
          的SelectedItem ={结合TheSelectedItem,模式=双向}/>

在您的视图模型声明组合框项目和使用财产来源,使其返回到视图

 列表<串GT; _source =新的List<串GT; {项目1,项目2,3项};
公开名单<串GT;资源
{
    {返回_source; }
}

然后定义它保存所选的项目一个属性。

 字符串_theSelectedItem = NULL;
公共字符串TheSelectedItem
{
    {返回_theSelectedItem; }
    集合{_theSelectedItem =价值; } // NotifyPropertyChanged
}

另外,不要忘记实现INotifyPropertyChanged接口,同时设置_source

I am new to C# and MVVM, and I've spent all day trying to get the value of a ComboBox to my ViewModel on SelectionChanged. I have managed to figure it out using either CallMethodAction or InvokeCommandAction with the resources:

  • System.Windows.Interactivity.dll
  • Microsoft.Expression.Interactions.dll

My problem is that both these methods return the value of the ComboBox before it has changed. Could anyone explain how to get the value after the change?

I have spent hours searching through SO and Google for a solution, so I wonder if others are too. Any advice will be appreciated!

My code is below:

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: My Solution

It turns out I didn't understand Binding well enough and instead was trying to implement something simple in a rather complicated way! Instead of using dependencies, I have now achieved what I needed using regular bindings. As an example, I've bound a TextBox to the SelectedIndex of the ComboBox, which gets updated using 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));
        }
    }
}

解决方案

Why not do it the simpler way

<ComboBox MaxHeight="25" 
          ItemsSource="{Binding Source}" 
          SelectedItem="{Binding TheSelectedItem, Mode=TwoWay}" />

In your ViewModel declare the combo box items and use a property "Source" to return it to the view

List<string> _source = new List<string>{"Item 1", "Item 2", "Item 3"};
public List<string> Source 
{ 
    get { return _source; } 
}

Then define one property which holds the selected item

string _theSelectedItem = null;
public string TheSelectedItem 
{ 
    get { return _theSelectedItem; } 
    set { _theSelectedItem = value; } // NotifyPropertyChanged
}

Also don't forget to implement the INotifyPropertyChanged interface while setting the _source

这篇关于WPF - MVVM:以后的SelectionChanged组合框值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆