Wpf 绑定到ViewModel属性的组合框在属性更改时不会更新

Wpf 绑定到ViewModel属性的组合框在属性更改时不会更新,wpf,data-binding,combobox,binding,Wpf,Data Binding,Combobox,Binding,我有一个组合框,其中填充了enum到ItemSource的可用项,并绑定到ViewModel属性WorkingMode: <ComboBox ItemsSource="{Binding Source={StaticResource WorkingModeEnum}}" SelectedItem="{Binding Path=WorkingMode, Mode=TwoWay" /> 当ViewModel属性将其值更改为All(枚举值之一)时,我获得了以下信息: 因此,看起来组合框收到

我有一个组合框,其中填充了enum到ItemSource的可用项,并绑定到ViewModel属性WorkingMode:

<ComboBox ItemsSource="{Binding Source={StaticResource WorkingModeEnum}}" SelectedItem="{Binding Path=WorkingMode, Mode=TwoWay" />
当ViewModel属性将其值更改为All(枚举值之一)时,我获得了以下信息:

因此,看起来组合框收到了新值,但没有任何更改(它仍然显示最后一个值,而不是全部)

任何帮助都会很好!谢谢

我的代码:

App.xaml:

 <Application x:Class="TestCombo.App"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Startup="OnStartup">
 <Application.Resources>

 </Application.Resources>
 </Application>
ViewModel.cs:

using System.ComponentModel;

namespace TestCombo
{
public class ViewModel : INotifyPropertyChanged
{
    public Model Model { get; private set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public ViewModel()
    {
        this.Model = new Model();
    }

    public TestEnum Test
    {
        get
        {
            return this.Model.Test;
        }
        set
        {
            if (this.Model.Test != value)
            {
                this.Model.Test = value;
                this.OnPropertyChanged("Test");
            }
        }

    }
    protected virtual void OnPropertyChanged(string name)
    {
        var handler = this.PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}
}
Model.cs:

namespace TestCombo
{
public class Model
{
    public TestEnum Test { get; set; }
}

public enum TestEnum
{
    Zero = 0,
    One = 1,
    Two = 2,
    Three = 3,
    Four = 4
}
}

您需要设置
UpdateSourceTrigger=PropertyChanged

SelectedItem="{Binding WorkingMode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
希望这有帮助

这将给你一个详细的解释
请发布您的虚拟机代码。我创建了一个测试项目,一切正常

样本代码:

<UserControl x:Class="WpfStackoverflow.ComboboxEnumSelectedValue"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:System="clr-namespace:System;assembly=mscorlib" 
         xmlns:local="clr-namespace:WpfStackoverflow" mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <ObjectDataProvider x:Key="WorkingModeEnum" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:WorkingMode"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</UserControl.Resources>
<StackPanel>
    <Button Content="Test Set All" Click="Button_Click" />
    <ComboBox ItemsSource="{Binding Source={StaticResource WorkingModeEnum}}" SelectedItem="{Binding Path=SelectedWorkingMode, Mode=TwoWay}"/>
    <TextBlock Text="{Binding SelectedWorkingMode, Mode=OneWay}"/>
</StackPanel>
枚举:

虚拟机:


我试过了,但没用,谢谢。在组合框中,默认值为PropertyChanged(在文本框中为LostFocus)。您的示例有效,而我的示例无效。我正在比较两者,看不出有什么不同。我知道了,我用MethodName=“GetNames”而不是MethodName=“GetValues”。我不知道有什么不同。
using System.ComponentModel;

namespace TestCombo
{
public class ViewModel : INotifyPropertyChanged
{
    public Model Model { get; private set; }

    public event PropertyChangedEventHandler PropertyChanged;

    public ViewModel()
    {
        this.Model = new Model();
    }

    public TestEnum Test
    {
        get
        {
            return this.Model.Test;
        }
        set
        {
            if (this.Model.Test != value)
            {
                this.Model.Test = value;
                this.OnPropertyChanged("Test");
            }
        }

    }
    protected virtual void OnPropertyChanged(string name)
    {
        var handler = this.PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}
}
namespace TestCombo
{
public class Model
{
    public TestEnum Test { get; set; }
}

public enum TestEnum
{
    Zero = 0,
    One = 1,
    Two = 2,
    Three = 3,
    Four = 4
}
}
SelectedItem="{Binding WorkingMode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
<UserControl x:Class="WpfStackoverflow.ComboboxEnumSelectedValue"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:System="clr-namespace:System;assembly=mscorlib" 
         xmlns:local="clr-namespace:WpfStackoverflow" mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <ObjectDataProvider x:Key="WorkingModeEnum" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:WorkingMode"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</UserControl.Resources>
<StackPanel>
    <Button Content="Test Set All" Click="Button_Click" />
    <ComboBox ItemsSource="{Binding Source={StaticResource WorkingModeEnum}}" SelectedItem="{Binding Path=SelectedWorkingMode, Mode=TwoWay}"/>
    <TextBlock Text="{Binding SelectedWorkingMode, Mode=OneWay}"/>
</StackPanel>
public partial class ComboboxEnumSelectedValue : UserControl
{
    private WorkingVM vm = new WorkingVM();
    public ComboboxEnumSelectedValue()
    {
        InitializeComponent();
        this.DataContext = vm;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        vm.SetAllModeForTesting();
    }


}
public enum WorkingMode
{
    Mode1,
    Mode2,
    Mode3,
    All
}
public class WorkingVM : INotifyPropertyChanged
{
    private WorkingMode _selectedmode;

    public void SetAllModeForTesting()
    {
        this.SelectedWorkingMode = WorkingMode.All;
    }

    public WorkingMode SelectedWorkingMode
    {
        get { return _selectedmode; }
        set { _selectedmode = value;
        this.OnPropertyChanged("SelectedWorkingMode");
        }
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyname)
    {
        var handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyname));
        }
    }

    #endregion
}