WPF MVVM Combobox SelectionChanged只是在重新加载ViewModel后才发生的。

问题描述 投票:0回答:1

我的问题是,在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>

ViewModel:

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

肯定是少了点什么,否则它就会变魔术;) 我只是不知道我错过了什么。欢迎任何帮助。

wpf mvvm combobox viewmodel selectionchanged
1个回答
0
投票

你没有调用OnPropertyChanged() forEmployerName,EmpDescription,EmpMotto,EmpLocation,EmpPhone,EmpEmail。

这就是为什么你的视图没有被更新的原因,为什么你实际上要使用这些单独的属性,而你可以直接使用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 事件。如果你没有做任何事情,而只是重新填充属性的话,请尝试删除它。

© www.soinside.com 2019 - 2024. All rights reserved.