WPF MVVM Combobox SelectionChanged 在重新加载 ViewModel 之后
WPF MVVM Combobox SelectionChanged just after reload the ViewModel
我的问题是,在 SelectionChanged 事件之后没有任何反应。 TextBox 没有获得任何与 ComboBox 相关的新值。当我重新加载 ViewModel(转到第 1 页并返回)时,TexBox 的新值与 ComboBox 相关。
下面你可以看到我到目前为止的内容。
查看:
<StackPanel Orientation="Vertical" Grid.Row="1">
<Border Width="150" Height="150" CornerRadius="80" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Center">
<Border.Background>
<ImageBrush ImageSource="/Assets/FEBSolution.png"/>
</Border.Background>
</Border>
<TextBlock x:Name="EmployerName" Text="{Binding EmployerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Margin="0 10 0 0" FontWeight="Bold"/>
<TextBlock x:Name="EmpDescription" Text="{Binding EmpDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="11" HorizontalAlignment="Center" Opacity="0.8"/>
<TextBlock x:Name="EmpMotto" Text="{Binding EmpMotto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="8" HorizontalAlignment="Center" Opacity="0.8"/>
<StackPanel Margin="20">
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Location" />
<TextBlock x:Name="EmpLocation" Text="{Binding EmpLocation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Phone" />
<TextBlock x:Name="EmpPhone" Text="{Binding EmpPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Email" />
<TextBlock x:Name="EmpEmail" Text="{Binding EmpEmail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
</StackPanel>
</StackPanel>
<ComboBox x:Name="cmbEmployer" Grid.Row="2" SelectedValuePath="ID" SelectedValue="{Binding ID}" ItemsSource="{Binding contractDetails}" SelectedItem="{Binding ContractSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="EmployerName" materialDesign:HintAssist.Hint="Employer" Width="200" HorizontalAlignment="Center" Margin="10">
<ie:Interaction.Triggers>
<ie:EventTrigger EventName="SelectionChanged">
<ie:InvokeCommandAction Command="{Binding SelectionChangedCommand, UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding ElementName=cmbEmployer, Path=SelectedItem}"/>
</ie:EventTrigger>
</ie:Interaction.Triggers>
</ComboBox>
视图模型:
private ContractDetail _contractSelectedItem;
public ContractDetail ContractSelectedItem
{
get { return _contractSelectedItem; }
set
{
_contractSelectedItem = value;
EmployerName = _contractSelectedItem.EmployerName;
EmpDescription = _contractSelectedItem.EmpDescription;
EmpMotto = _contractSelectedItem.EmpMotto;
EmpLocation = _contractSelectedItem.EmpLocation;
EmpPhone = _contractSelectedItem.EmpPhone;
EmpEmail = _contractSelectedItem.EmpEmail;
OnPropertyChanged(nameof(ContractSelectedItem));
}
}
public List<ContractDetail> contractDetails { get; set; }
#region Public all Commands
//Command for change User
public ICommand ChangeUserCommand { get; private set; }
public ICommand CloseWindowCommand { get; private set; }
public ICommand SelectionChangedCommand { get; private set; }
#endregion
//PRWContext for general use
private PRWContext context = new PRWContext();
public ApplicationSettingViewModel()
{
// Load the data from PRW Database
LoadUserData();
BindContractComboBox();
//Commands
ChangeUserCommand = new RelayCommand(() => ExecuteChangeUserCommand());
CloseWindowCommand = new RelayCommand(() => ExecuteCloseWindowCommand());
SelectionChangedCommand = new RelayCommand(() => ExecuteSelectionChangedCommand());
}
private void ExecuteCloseWindowCommand()
{
foreach (Window window in Application.Current.Windows)
{
if (window is ApplicationSettingWindow)
{
window.Close();
break;
}
}
}
private void ExecuteChangeUserCommand()
{
UserSettingWindow view = new UserSettingWindow();
view.Show();
foreach (Window window in Application.Current.Windows)
{
if (window is ApplicationSettingWindow)
{
window.Close();
break;
}
}
}
private void ExecuteSelectionChangedCommand()
{
var item = context.ContractDetails.ToList();
contractDetails = item;
}
//Load the user data
private void LoadUserData()
{
UserName = Settings.Default["UserName"].ToString();
JobDescription = Settings.Default["UsrJobDescription"].ToString();
Motto = Settings.Default["UsrMotto"].ToString();
Street = Settings.Default["UsrStreet"].ToString();
City = Settings.Default["UsrCity"].ToString();
Country = Settings.Default["UsrCountry"].ToString();
PhoneNumber = Settings.Default["UsrPhoneNumber"].ToString();
Email = Settings.Default["UsrEmail"].ToString();
}
private void BindContractComboBox()
{
var item = context.ContractDetails.ToList();
contractDetails = item;
}
#region PropertyChanged EventHandler
//propertychanged eventhandler
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
肯定是少了什么东西,否则它会产生魔力 ;) 我只是不知道我漏掉了什么东西。欢迎任何帮助。
您调用 OnPropertyChanged() 的目的不是
雇主姓名,
员工描述,
企业格言,
就业地点,
手机,
电子邮件
这就是为什么您的视图没有得到更新,以及为什么在您可以直接使用 ContractSelectedItem 时实际使用这些单独的属性。您可以像这样访问嵌套属性 "ContractSelectedItem.EmployerName"
在您的视图模型中试试这个
private ContractDetail _contractSelectedItem;
public ContractDetail ContractSelectedItem
{
get { return _contractSelectedItem; }
set
{
_contractSelectedItem = value;
OnPropertyChanged(nameof(ContractSelectedItem));
}
}
并像这样更改视图的绑定
<StackPanel Orientation="Vertical" Grid.Row="1">
<Border Width="150" Height="150" CornerRadius="80" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Center">
<Border.Background>
<ImageBrush ImageSource="/Assets/FEBSolution.png"/>
</Border.Background>
</Border>
<TextBlock x:Name="EmployerName" Text="{Binding ContractSelectedItem.EmployerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Margin="0 10 0 0" FontWeight="Bold"/>
<TextBlock x:Name="EmpDescription" Text="{Binding ContractSelectedItem.EmpDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="11" HorizontalAlignment="Center" Opacity="0.8"/>
<TextBlock x:Name="EmpMotto" Text="{Binding ContractSelectedItem.EmpMotto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="8" HorizontalAlignment="Center" Opacity="0.8"/>
<StackPanel Margin="20">
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Location" />
<TextBlock x:Name="EmpLocation" Text="{Binding ContractSelectedItem.EmpLocation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Phone" />
<TextBlock x:Name="EmpPhone" Text="{Binding ContractSelectedItem.EmpPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Email" />
<TextBlock x:Name="EmpEmail" Text="{Binding ContractSelectedItem.EmpEmail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
</StackPanel>
</StackPanel>
<ComboBox x:Name="cmbEmployer" Grid.Row="2" SelectedValuePath="ID" SelectedValue="{Binding ID}" ItemsSource="{Binding contractDetails}" SelectedItem="{Binding ContractSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="EmployerName" materialDesign:HintAssist.Hint="Employer" Width="200" HorizontalAlignment="Center" Margin="10">
<ie:Interaction.Triggers>
<ie:EventTrigger EventName="SelectionChanged">
<ie:InvokeCommandAction Command="{Binding SelectionChangedCommand, UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding ElementName=cmbEmployer, Path=SelectedItem}"/>
</ie:EventTrigger>
</ie:Interaction.Triggers>
</ComboBox>
此外,当每次选择更改时您只是重新填充 contractDetails 属性 时,似乎没有理由使用 SelectionChanged 事件。如果您什么都不做,请尝试将其删除,然后重新填充 属性.
我的问题是,在 SelectionChanged 事件之后没有任何反应。 TextBox 没有获得任何与 ComboBox 相关的新值。当我重新加载 ViewModel(转到第 1 页并返回)时,TexBox 的新值与 ComboBox 相关。
下面你可以看到我到目前为止的内容。
查看:
<StackPanel Orientation="Vertical" Grid.Row="1">
<Border Width="150" Height="150" CornerRadius="80" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Center">
<Border.Background>
<ImageBrush ImageSource="/Assets/FEBSolution.png"/>
</Border.Background>
</Border>
<TextBlock x:Name="EmployerName" Text="{Binding EmployerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Margin="0 10 0 0" FontWeight="Bold"/>
<TextBlock x:Name="EmpDescription" Text="{Binding EmpDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="11" HorizontalAlignment="Center" Opacity="0.8"/>
<TextBlock x:Name="EmpMotto" Text="{Binding EmpMotto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="8" HorizontalAlignment="Center" Opacity="0.8"/>
<StackPanel Margin="20">
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Location" />
<TextBlock x:Name="EmpLocation" Text="{Binding EmpLocation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Phone" />
<TextBlock x:Name="EmpPhone" Text="{Binding EmpPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Email" />
<TextBlock x:Name="EmpEmail" Text="{Binding EmpEmail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
</StackPanel>
</StackPanel>
<ComboBox x:Name="cmbEmployer" Grid.Row="2" SelectedValuePath="ID" SelectedValue="{Binding ID}" ItemsSource="{Binding contractDetails}" SelectedItem="{Binding ContractSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="EmployerName" materialDesign:HintAssist.Hint="Employer" Width="200" HorizontalAlignment="Center" Margin="10">
<ie:Interaction.Triggers>
<ie:EventTrigger EventName="SelectionChanged">
<ie:InvokeCommandAction Command="{Binding SelectionChangedCommand, UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding ElementName=cmbEmployer, Path=SelectedItem}"/>
</ie:EventTrigger>
</ie:Interaction.Triggers>
</ComboBox>
视图模型:
private ContractDetail _contractSelectedItem;
public ContractDetail ContractSelectedItem
{
get { return _contractSelectedItem; }
set
{
_contractSelectedItem = value;
EmployerName = _contractSelectedItem.EmployerName;
EmpDescription = _contractSelectedItem.EmpDescription;
EmpMotto = _contractSelectedItem.EmpMotto;
EmpLocation = _contractSelectedItem.EmpLocation;
EmpPhone = _contractSelectedItem.EmpPhone;
EmpEmail = _contractSelectedItem.EmpEmail;
OnPropertyChanged(nameof(ContractSelectedItem));
}
}
public List<ContractDetail> contractDetails { get; set; }
#region Public all Commands
//Command for change User
public ICommand ChangeUserCommand { get; private set; }
public ICommand CloseWindowCommand { get; private set; }
public ICommand SelectionChangedCommand { get; private set; }
#endregion
//PRWContext for general use
private PRWContext context = new PRWContext();
public ApplicationSettingViewModel()
{
// Load the data from PRW Database
LoadUserData();
BindContractComboBox();
//Commands
ChangeUserCommand = new RelayCommand(() => ExecuteChangeUserCommand());
CloseWindowCommand = new RelayCommand(() => ExecuteCloseWindowCommand());
SelectionChangedCommand = new RelayCommand(() => ExecuteSelectionChangedCommand());
}
private void ExecuteCloseWindowCommand()
{
foreach (Window window in Application.Current.Windows)
{
if (window is ApplicationSettingWindow)
{
window.Close();
break;
}
}
}
private void ExecuteChangeUserCommand()
{
UserSettingWindow view = new UserSettingWindow();
view.Show();
foreach (Window window in Application.Current.Windows)
{
if (window is ApplicationSettingWindow)
{
window.Close();
break;
}
}
}
private void ExecuteSelectionChangedCommand()
{
var item = context.ContractDetails.ToList();
contractDetails = item;
}
//Load the user data
private void LoadUserData()
{
UserName = Settings.Default["UserName"].ToString();
JobDescription = Settings.Default["UsrJobDescription"].ToString();
Motto = Settings.Default["UsrMotto"].ToString();
Street = Settings.Default["UsrStreet"].ToString();
City = Settings.Default["UsrCity"].ToString();
Country = Settings.Default["UsrCountry"].ToString();
PhoneNumber = Settings.Default["UsrPhoneNumber"].ToString();
Email = Settings.Default["UsrEmail"].ToString();
}
private void BindContractComboBox()
{
var item = context.ContractDetails.ToList();
contractDetails = item;
}
#region PropertyChanged EventHandler
//propertychanged eventhandler
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
肯定是少了什么东西,否则它会产生魔力 ;) 我只是不知道我漏掉了什么东西。欢迎任何帮助。
您调用 OnPropertyChanged() 的目的不是 雇主姓名, 员工描述, 企业格言, 就业地点, 手机, 电子邮件
这就是为什么您的视图没有得到更新,以及为什么在您可以直接使用 ContractSelectedItem 时实际使用这些单独的属性。您可以像这样访问嵌套属性 "ContractSelectedItem.EmployerName"
在您的视图模型中试试这个
private ContractDetail _contractSelectedItem;
public ContractDetail ContractSelectedItem
{
get { return _contractSelectedItem; }
set
{
_contractSelectedItem = value;
OnPropertyChanged(nameof(ContractSelectedItem));
}
}
并像这样更改视图的绑定
<StackPanel Orientation="Vertical" Grid.Row="1">
<Border Width="150" Height="150" CornerRadius="80" BorderThickness="1" BorderBrush="Gray" HorizontalAlignment="Center">
<Border.Background>
<ImageBrush ImageSource="/Assets/FEBSolution.png"/>
</Border.Background>
</Border>
<TextBlock x:Name="EmployerName" Text="{Binding ContractSelectedItem.EmployerName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Margin="0 10 0 0" FontWeight="Bold"/>
<TextBlock x:Name="EmpDescription" Text="{Binding ContractSelectedItem.EmpDescription, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="11" HorizontalAlignment="Center" Opacity="0.8"/>
<TextBlock x:Name="EmpMotto" Text="{Binding ContractSelectedItem.EmpMotto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="8" HorizontalAlignment="Center" Opacity="0.8"/>
<StackPanel Margin="20">
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Location" />
<TextBlock x:Name="EmpLocation" Text="{Binding ContractSelectedItem.EmpLocation, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Phone" />
<TextBlock x:Name="EmpPhone" Text="{Binding ContractSelectedItem.EmpPhone, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0 3" HorizontalAlignment="Left">
<materialDesign:PackIcon Kind="Email" />
<TextBlock x:Name="EmpEmail" Text="{Binding ContractSelectedItem.EmpEmail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10 0"/>
</StackPanel>
</StackPanel>
</StackPanel>
<ComboBox x:Name="cmbEmployer" Grid.Row="2" SelectedValuePath="ID" SelectedValue="{Binding ID}" ItemsSource="{Binding contractDetails}" SelectedItem="{Binding ContractSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="EmployerName" materialDesign:HintAssist.Hint="Employer" Width="200" HorizontalAlignment="Center" Margin="10">
<ie:Interaction.Triggers>
<ie:EventTrigger EventName="SelectionChanged">
<ie:InvokeCommandAction Command="{Binding SelectionChangedCommand, UpdateSourceTrigger=PropertyChanged}" CommandParameter="{Binding ElementName=cmbEmployer, Path=SelectedItem}"/>
</ie:EventTrigger>
</ie:Interaction.Triggers>
</ComboBox>
此外,当每次选择更改时您只是重新填充 contractDetails 属性 时,似乎没有理由使用 SelectionChanged 事件。如果您什么都不做,请尝试将其删除,然后重新填充 属性.