我有一个ComboBox填充了枚举项目源的枚举项,并绑定到ViewModel属性WorkingMode:
<ComboBox ItemsSource="{Binding Source={StaticResource WorkingModeEnum}}" SelectedItem="{Binding Path=WorkingMode, Mode=TwoWay" />
如果我手动更改ComboBox的选定项,ViewModel属性会按预期更改其值,但如果我更改ViewModel的属性值,则ComboBox不会更改显示给用户的内容。
ViewModel实现了INotifyPropertyChanged,并在值更改时引发事件。更重要的是,使用以下命令激活WPF日志记录:
diag:PresentationTraceSources.TraceLevel=High
当ViewModel属性将其值更改为All(其中一个枚举值)时,我得到以下信息:
System.Windows.Data Warning: 86 : BindingExpression (hash=50934842): Update - got raw value 'All'
System.Windows.Data Warning: 89 : BindingExpression (hash=50934842): Update - implicit converter produced 'All'
System.Windows.Data Warning: 90 : BindingExpression (hash=50934842): Update - using final value 'All'
所以看起来ComboBox收到了新值,但没有任何改变(它仍然显示最后一个值,除了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>
View.xaml:
<Window x:Class="TestCombo.View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:TestCombo="clr-namespace:TestCombo"
Title="View" Height="300" Width="300">
<Window.Resources>
<ObjectDataProvider x:Key="TestEnum" MethodName="GetNames" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="TestCombo:TestEnum"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<StackPanel>
<ComboBox ItemsSource="{Binding Source={StaticResource TestEnum}}" SelectedItem="{Binding Path=Test, Mode=TwoWay, PresentationTraceSources.TraceLevel=High}"/>
<Button Height="23" Name="button1" VerticalAlignment="Bottom" Click="button1_Click">Button</Button>
<TextBlock Grid.Row="2" Text="{Binding Test, Mode=OneWay}"/>
</StackPanel>
</Grid>
View.xaml.cs:
using System.Windows;
namespace TestCombo
{
public partial class View : Window
{
public View()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
((ViewModel) this.DataContext).Test = TestEnum.Three;
}
}
}
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
}
}
答案 0 :(得分:1)
发布您的VM代码。我创建了一个测试项目,一切正常。
SampleCode:
<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>
的.cs
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
}
VM:
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
}
答案 1 :(得分:0)
您需要设置UpdateSourceTrigger=PropertyChanged
SelectedItem="{Binding WorkingMode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
希望这会有所帮助
这将给你一个详细的解释 UpdateSourceTrigger – DataBinding