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 事件。如果您什么都不做,请尝试将其删除,然后重新填充 属性.