首页 > 解决方案 > 如何使用 ICommand 将组合框事件绑定到视图模型

问题描述

我对 MVVM 比较陌生,我想将我的视图绑定到视图模型。我有很多代码要从 CodeBehind 移到 ViewModel 类中。

我想做的是将 ComboBox 事件绑定到相应的 ViewModel ICommand 方法。我希望 ComboBox 在视图加载时显示“CompanyB”,并且当我进行选择时,ComboBox 应该给我“CompanyA”、“CompanyB”和“CompanyC”作为可供选择的选项。

选择公司后,以下 2 个文本框的值

Nachbest.Empf_Ansprechpartner

Nachbest.Empfaenger_Mail

必须相应改变。

问题在于我的代码 ComboBox 和文本框都保持为空,并且在组合框中也没有任何选择。

你能帮我找到我在这里缺少的东西吗?提前感谢您的帮助!

XAML (neueNachbestellung.xaml):

<Window xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
    <Grid>
        <StackPanel Grid.Column="0" Margin="25,25,0,0" x:Name="leftStPnl">
            <ComboBox x:Name="cboxEmpfaenger" 
                      ItemsSource="{Binding Empf}" 
                      Text="{Binding Empfaenger}" 
                      FontSize="12" Width="150" Margin="118,0,0,0"                      
                      SelectedItem="{Binding SelValue}">
            </ComboBox>
            <TextBox x:Name="txtEmpfAnsprechpartner" Text="{Binding Empf_Ansprechpartner}" FontSize="12" IsEnabled="False" Width="150" Margin="50,0,0,0"/>    
            <TextBox x:Name="txtEmpfMail" Text="{Binding Empfaenger_Mail}" FontSize="12" IsEnabled="False" Width="150" Margin="73,0,0,0"/>
        </StackPanel>
    </Grid>
</Window>

代码背后(neueNachbestellung.xaml.cs):

public neueNachbestellung(string someId) 
{
    InitializeComponent();
    this.DataContext = new neueNachbestellungViewModel(someId);
}

查看模型(neueNachbestellungViewModel.cs)

public class neueNachbestellungViewModel: INotifyPropertyChanged
{
public ICommand LoadCombobox => new DelegateCommand<object>(ExecuteLoadCombobox);
public ICommand ComboboxSelectionChanged => new DelegateCommand<object>(ExecuteComboboxSelectionChanged);
public Nachbestellung Nachbest { get; set; }
private object someObject;
private ObservableCollection<string> _empf;
        public ObservableCollection<string> Empf
        {
            get { return _empf; }
            set
            {
                _empf = value;
                OnPropertyChanged("Empf");
            }
        }
        private string _selValue = "12";
        public string SelValue  
        {
            get { return _selValue; }
            set
            {
                _selValue = value;
                OnPropertyChanged("SelValue");
            }
        }

 public event PropertyChangedEventHandler PropertyChanged;
        public virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

public neueNachbestellungViewModel(string id)
{

    this.Artikel = new ArtikelViewModel();
    this.ArtikelList = new ObservableCollection<Artikel>();
    InitializeReorderModel(id);    
    ExecuteComboboxSelectionChanged(someObject);                        
}

public void InitializeReorderModel(string id)
{
    //set the MODEL
    this.Nachbest = new Nachbestellung();

    //Retrieve and set some values on *VIEW LOAD*!
    var dbOracle = new Datenbank();
    this.Nachbest.Bv = dbOracle.GetBauvorhaben(hv);
    this.Nachbest.Hv = hv;
    this.Nachbest.Bauleiter = dbOracle.GetBauleiter(hv);
    this.Nachbest.Projektleiter = dbOracle.GetProjektleiter(hv);
}

private void ExecuteLoadCombobox(object param)
{
    Empf = new ObservableCollection<string>()
    {
        "CompanyA",
        "CompanyB",
        "CompanyC"         
    };

    //Company B is the standard selection on combobox load                     
    Nachbest.Empf_Ansprechpartner = "CompanyB";
    Nachbest.Empfaenger_Mail = "orders@companyB.com";
}

private void ExecuteComboboxSelectionChanged(object param)
{
    Empf = new ObservableCollection<string>()
    {
        "CompanyA",
        "CompanyB",
        "CompanyC"             
    };

    switch (SelValue)
    {

        case "CompanyA":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyA";
                Nachbest.Empfaenger_Mail = "service@companyA.com";
            }
            break;

        case "CompanyB":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyB";
                Nachbest.Empfaenger_Mail = "orders@companyB.com";
            }
            break;

        case "CompanyC":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyC";
                Nachbest.Empfaenger_Mail = "info@companyC.com";
            }
            break;

        default:
            MessageBox.Show("Something went wrong with the company selection!");
            break;
    }
}
}

查看片段

在此处输入图像描述

标签: c#wpfxamlmvvmicommand

解决方案


这是我快速而肮脏的解决方案。它做了它需要做的事情,我的代码中不再有这些 click_button、selection_changed 事件,而是在我的视图模型中。这就是我现在所需要的。显然不是一个优雅的解决方案,但它正在工作。我希望我可以帮助一些将来遇到类似问题的开发人员。附带说明:在这种情况下,视图模型中的 ICommand 属性不是必需的,但我使用它们来处理视图中的按钮单击事件。如果您的应用程序中不需要 DelegateCommand 类,您可以将它们替换为您自己的属性。

XAML (neueNachbestellung.xaml):

<Window>
    <Grid>
        <StackPanel Grid.Column="0" Margin="25,25,0,0" x:Name="leftStPnl">
            <ComboBox x:Name="cboxEmpfaenger" 
                      ItemsSource="{Binding Empf}" 
                      Text="{Binding Empfaenger}" 
                      FontSize="12" Width="150" Margin="118,0,0,0"                      
                      SelectedItem="{Binding SelValue}">
            </ComboBox>
            <TextBox x:Name="txtEmpfAnsprechpartner" DataContext="{Binding Nachbest}" Text="{Binding Empf_Ansprechpartner}" FontSize="12" IsEnabled="False" Width="150" Margin="50,0,0,0"/>    
            <TextBox x:Name="txtEmpfMail" DataContext="{Binding Nachbest}" Text="{Binding Empfaenger_Mail}" FontSize="12" IsEnabled="False" Width="150" Margin="73,0,0,0"/>
        </StackPanel>
    </Grid>
</Window>

代码背后(neueNachbestellung.xaml.cs):

public neueNachbestellung(string someId) 
{
    InitializeComponent();
    this.DataContext = new neueNachbestellungViewModel(someId);
}

neueNachbestellungViewModel.cs:

public class neueNachbestellungViewModel: INotifyPropertyChanged
{
//public ICommand LoadCombobox => new DelegateCommand<object>(ExecuteLoadCombobox);
public ICommand ComboboxSelectionChanged => new DelegateCommand<object>(ExecuteComboboxSelectionChanged);
public Nachbestellung Nachbest { get; set; }
private object someObject; //DelegateCommand.cs requires an argument
private ObservableCollection<string> _empf;
        public ObservableCollection<string> Empf
        {
            get { return _empf; }
            set
            {
                _empf = value;
                OnPropertyChanged("Empf");
            }
        }
        private string _selValue = "CompanyB"; //default value
        public string SelValue  
        {
            get { return _selValue; }
            set
            {
                _selValue = value;
                OnPropertyChanged("SelValue");
 switch (SelValue)
    {

        case "CompanyA":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyA";
                Nachbest.Empfaenger_Mail = "service@companyA.com";
            }
            break;

        case "CompanyB":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyB";
                Nachbest.Empfaenger_Mail = "orders@companyB.com";
            }
            break;

        case "CompanyC":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyC";
                Nachbest.Empfaenger_Mail = "info@companyC.com";
            }
            break;

        default:
            MessageBox.Show("Something went wrong with the company selection!");
            break;
    }
//setting the Empfaenger property here with the current selected value is necessary for the database insert later on!
Nachbest.Empfaenger = SelValue;
            }
        }

 public event PropertyChangedEventHandler PropertyChanged;
        public virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

public neueNachbestellungViewModel(string id)
{

    this.Artikel = new ArtikelViewModel();
    this.ArtikelList = new ObservableCollection<Artikel>();
    InitializeReorderModel(id);    
    ExecuteComboboxSelectionChanged(someObject);                        
}

public void InitializeReorderModel(string id)
{
    //set the MODEL
    this.Nachbest = new Nachbestellung();

    //Retrieve and set some values on *VIEW LOAD*!
    var dbOracle = new Datenbank();
    this.Nachbest.Bv = dbOracle.GetBauvorhaben(hv);
    this.Nachbest.Hv = hv;
    this.Nachbest.Bauleiter = dbOracle.GetBauleiter(hv);
    this.Nachbest.Projektleiter = dbOracle.GetProjektleiter(hv);
}

private void ExecuteComboboxSelectionChanged(object param)
{
    Empf = new ObservableCollection<string>()
    {
        "CompanyA",
        "CompanyB",
        "CompanyC"             
    };
Nachbest.Empf_Ansprechpartner = "CompanyB";
            Nachbest.Empfaenger_Mail = "orders@companyB.com";
            Nachbest.Empfaenger = SelValue; //if this is left out and there is no selection (just the default remaining unchanged!), Nachbest.Empfaenger will be null!
}
}

推荐阅读