我之前可以看到这个问题,但似乎没有什么对我有用。
我有一个wpf桌面应用程序。
我有这个组合框:
<ComboBox ItemsSource="{Binding Users, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Value.Login"
SelectedValue="{Binding SelectedManagerUser,
Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
SelectedValuePath="Value"
IsSynchronizedWithCurrentItem="True" />
数据源是字典对象:
public Dictionary<string,UserRecord> Users
{
get
{
//get data
}
set { _Users = value; RaisePropertyChanged(Constants.VM_Users); }
}
我在MVVM中添加了一个新条目并更新了数据。
然后我在mvvm中设置了所选项目:
private UserRecord _selectedManagerUser;
public UserRecord SelectedManagerUser
{
get
{
return _selectedManagerUser;
}
set
{
_selectedManagerUser = value;
RaisePropertyChanged("SelectedManagerUser");
}
}
SelectedManagerUser = Users[temp];
public class UserRecord : ViewModelBase
{
private int _Active;
private int _UserRecordId;
private string _UserRef;
private string _FName;
private string _SName;
private string _Login;
private string _Salt;
private int _IsAdmin;
private string _FullName;
private string _Branch;
private string _Position;
private string _Department;
public int Disabled { get { return _Active; } set { _Active = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_Active); } }
public int UserRecordId { get { return _UserRecordId; } set { _UserRecordId = value; RaisePropertyChanged("UserRecordId"); } }
public string UserRef { get { return _UserRef; } set { _UserRef = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_UserRef); } }
public string FName { get { return _FName; } set { _FName = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_FName); } }
public string SName { get { return _SName; } set { _SName = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_SName); } }
public string Login { get { return _Login; } set { _Login = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_Login); } }
public string Salt { get { return _Salt; } set { _Salt = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_Salt); } }
public int IsAdmin { get { return _IsAdmin; } set { _IsAdmin = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_IsAdmin); } }
public string Branch { get { return _Branch; } set { _Branch = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_Branch); } }
public string Position { get { return _Position; } set { _Position = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_Position); } }
public string Department { get { return _Department; } set { _Department = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_Department); } }
public string FullName { get { return FName + ", " + SName; } set { _FullName = value; RaisePropertyChanged(InformedWorkerCommon.Constants.VM_Fullname); } }
}
我知道新项目已添加,因为 -
组合框只显示一个空值。
我还能尝试其他什么吗?
感谢
答案 0 :(得分:0)
您的SelectedManagerUser属性应更改为此属性。 SelectedManagerUser属性设置为新值,但您不会引发该事件,因此不会更新UI。
private UserRecord _selectedManagerUser;
public UserRecord SelectedManagerUser
{
get
{
return _selectedManagerUser;
}
set
{
_selectedManagerUser = value;
RaisePropertyChanged("SelectedManagerUser");
}
}
答案 1 :(得分:0)
不确定您身边出了什么问题,但查看有效的解决方案可能会有所帮助。
XAML:
<ComboBox ItemsSource="{Binding Users}"
DisplayMemberPath="Value.Name"
SelectedValue="{Binding SelectedUser}"
SelectedValuePath="Value" />
代码背后:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += WindowLoaded;
var vm = new ViewModel();
vm.Users.Add("u1", new UserRecord { Name = "User 1" });
vm.Users.Add("u2", new UserRecord { Name = "User 2" });
vm.Users.Add("u3", new UserRecord { Name = "User 3" });
DataContext = vm;
}
private void WindowLoaded(object sender, RoutedEventArgs e)
{
// make sure it works after DataContext was set
var vm = (ViewModel)DataContext;
vm.SelectedUser = vm.Users["u2"];
}
}
public class UserRecord
{
public string Name { get; set; }
}
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public Dictionary<string, UserRecord> Users { get; }
= new Dictionary<string, UserRecord>();
private UserRecord selectedUser;
public UserRecord SelectedUser
{
get { return selectedUser; }
set
{
selectedUser = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(SelectedUser)));
}
}
}
答案 2 :(得分:0)
从Prism
下载Nuget
并从BindableBase
继承您的课程。
使用后:
private UserRecord selectedManagerUser;
public UserRecord SelectedManagerUser
{
get { return this.selectedManagerUser; }
set { this.SetProperty(ref this.selectedManagerUser, value); }
}
答案 3 :(得分:0)
两件事之一可能导致这种情况。首先,可能是因为您没有将SelectedManagerUser
设置为UserRecord
的不在字典中的实例,或者字典仍然很难进行数据绑定。 Lemme盖住他们两个。
当您使用ItemsSource
和SelectedItem
绑定时,如果您希望在UI中反映SelectedItem
更改,则必须将其设置为可在{{ItemsSource
内找到的实例1}}。默认情况下,控件将在源中查找与所选项目相同的项目。我99%肯定会使用IEquatable<T>
而不是参考检查您的项目是否实现了它。
如果那不是你的问题,那就是因为字典很难进行数据绑定。
字典对于数据绑定是可怕的。太可怕了。如果您需要键控集合并且想要绑定它,请创建一个扩展KeyedCollection的自定义集合。通过一些额外的工作,TItem可以实现INPC(使密钥只读,tho),集合可以实现INCC。适用于绑定。为什么我提这个?请继续阅读...
您的问题是,在ComboBox中,SelectedItem
实际上是KeyValuePair<string,UserRecord>
类型,而不是UserRecord
。所以绑定不起作用。如果你抓住Snoop的副本并在运行时检查绑定,你会看到这一点。
问题在于控制器并不知道插头关于字典的蹲下。它只知道IEnumerable<T>
。 Dictionary<K,T>
实现IEnumerable<KeyValuePair<K,T>>
,因此控件会为每个键值对创建一个项目。 SelectedItem也是一个键值对。因此,当您将其绑定到类型UserRecord
的属性时,是的,它能够使用SelectedValuePath正确设置值,但它不能(不)[忍者编辑:除非此行为已更改在过去的几年中:/]迭代枚举,以便在视图模型中设置值时找到正确的键值对。
如果UserRecord
的键值是该类型中的属性,那么肯定会为它创建一个KeyedCollection。 KeyedCollection<Tkey,TItem>
实现了&#39; IEnumerable`,因此它可以与绑定无缝协作。如果没有,请将其包装在代理中,或添加属性。
当我说&#34;将它包装在代理中时,任何人都会说'&34;什么,比如KeyValuePair?&#34;我打算通过互联网打你。代理成为您绑定的值。不要浪费你的时间SelectedValuePath
胡说八道。直接与代理人合作。当你需要你的值时,在最后一刻提取它,而不是在绑定执行后立即提取它。