c# - 如何使用 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;
}
}
}
查看片段:
解决方案
这是我快速而肮脏的解决方案。它做了它需要做的事情,我的代码中不再有这些 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!
}
}
推荐阅读
- c# - Azure API(Graph 或 REST)中的 AAD 用户默认权限(UserSettings)在哪里?
- android - Firebase Analytics 配置受众位置跟踪
- typo3 - 错字3 将 frame_class 附加到布局
- pdf-generation - 当我在 Play 商店中上传应用程序但拒绝应用程序时(因为 Android 11 权限问题)
- node.js - 得到“错误:解决方法被过度指定”?在 beforeEach 和 afterEach
- javascript - How can i make dynamic selecte box in a formula using laravel 8
- vba - VBA - CommandBars_OnUPdate - Which action /control has been triggered on the event?
- mysql - 不能在单个 Mysql 查询中执行 MAX 、 COUNT
- moqui - What is meaning of field item_type_gl_account.direction in moqui?
- angular - Can an angular function be partially async?