简体   繁体   English

如何使用 ICommand 将 combobox 事件绑定到视图模型

[英]How to bind combobox events to viewmodel with ICommand

I am relatively new to MVVM and I want to bind my view to the view model.我对 MVVM 比较陌生,我想将我的视图绑定到视图 model。 I have a lot of code to move from the CodeBehind into the ViewModel class.我有很多代码要从 CodeBehind 移动到 ViewModel class。

What I would like to do is binding the ComboBox Events to the corresponding ViewModel ICommand methods.我想做的是将 ComboBox 事件绑定到相应的 ViewModel ICommand 方法。 I want the ComboBox to show "CompanyB" when the view loads and when I make a selection, the ComboBox should give me "CompanyA", "CompanyB" and "CompanyC" as options to select from.我希望 ComboBox 在视图加载时显示“CompanyB”,当我进行选择时,ComboBox 应该给我“CompanyA”、“CompanyB”和“CompanyC”作为 Z99938282F040718429941 的选项。

After a company was selected, the values of the 2 textboxes below选择公司后,以下 2 个文本框的值

Nachbest.Empf_Ansprechpartner Nachbest.Empf_Ansprechpartner

Nachbest.Empfaenger_Mail Nachbest.Empfaenger_Mail

must change accordingly.必须相应改变。

The problem is with my code both the ComboBox and the textboxes remain empty and there is also nothing to choose from inside the combobox.问题在于我的代码 ComboBox 和文本框仍然为空,并且在 combobox 内部也没有任何选择。

Could you please help me find what I am missing here?你能帮我找到我在这里缺少的东西吗? Thanks in advance for any help!提前感谢您的帮助!

XAML (neueNachbestellung.xaml): 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>

Code Behind (neueNachbestellung.xaml.cs):后面的代码(neueNachbestellung.xaml.cs):

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

View Model(neueNachbestellungViewModel.cs) :查看模型(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;
    }
}
}

View Fragment :查看片段

在此处输入图像描述

This is my quick & dirty solution.这是我快速而肮脏的解决方案。 It does what it needs to and I don't have these click_button, selection_changed events inside my code behind anymore but inside my view model.它做了它需要做的事情,我的代码中不再有这些 click_button、selection_changed 事件,而是在我的视图 model 中。 That is all I need for now.这就是我现在所需要的。 Obviously not an elegant solution but it is working.显然不是一个优雅的解决方案,但它正在工作。 I hope I can help some developers with it in the future who run into similar problems.我希望我可以帮助一些将来遇到类似问题的开发人员。 Just a side note: The ICommand properties inside the view model are not necessary in this scenario but I am using them to handle button click events in the view.附带说明:在这种情况下,视图 model 中的 ICommand 属性不是必需的,但我使用它们来处理视图中的按钮单击事件。 You can replace them with your own properties if you don't need the DelegateCommand class in your application.如果您的应用程序中不需要 DelegateCommand class,您可以将它们替换为您自己的属性。

XAML (neueNachbestellung.xaml): 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>

Code Behind (neueNachbestellung.xaml.cs):后面的代码(neueNachbestellung.xaml.cs):

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

neueNachbestellungViewModel.cs: 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!
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM