WPF:我可以绑定到组合框的 SelectedValue 吗?
WPF : Is it possible for me to bind to the SelectedValue of a combo box?
我有一个数据 table,其中保存了用户信息列表。
为了简单地与 table 交互,我创建了一个 class,它接受用户 ID(table 的主键),并查询 table 检索用户信息:
public class User {
/// <summary>
/// Initialize a new User Object.
/// </summary>
/// <param name="ID">User UUID</param>
public User( string ID ) {
this.UserID = ID;
}
/// <summary>
/// Get User UUID
/// </summary>
public string UserID { get; private set; }
/// <summary>
/// Get or Set User Name
/// </summary>
public string UserName {
get { return this.Get( "User_Name" ); }
set { this.Set( "User_Name", value ); }
}
/// <summary>
/// Get or Set User Company
/// </summary>
public string UserCompany {
get { return this.Get( "User_Company" ); }
set { this.Set( "User_Company", value ); }
}
/// <summary>
/// Get or Set User Email
/// </summary>
public string UserEmail {
get { return this.Get( "User_Email" ); }
set { this.Set( "User_Email", value ); }
}
/// <summary>
/// Get or Set User Phone Number
/// </summary>
public string UserPhone {
get { return this.Get( "User_Phone" ); }
set { this.Set( "User_Phone", value ); }
}
/// <summary>
/// Get string representation of this User.
/// </summary>
/// <returns>User Name</returns>
public override string ToString( ) { return this.UserName; }
private string Get( string fromField ) {
return RegistrationTables.UsersTable == null ? "USER TABLE EMPTY" :
RegistrationEntries.Get<string>( RegistrationTables.UsersTable, "User_ID", this.UserID, fromField );
}
private void Set( string toField, string value ) {
if ( RegistrationTables.UsersTable == null )
return;
RegistrationEntries.Set( RegistrationTables.UsersTable, "User_ID", this.UserID, toField, value );
}
}
现在我还有一个 ComboBox,我将其数据源设置为用户列表:
this.cbxUsers.SetBinding( ItemsControl.ItemsSourceProperty, new Binding( ) { Source = RegistrationTables.GetUsers( this.SystemID ) } );
public static List<RegistrationEntries.User> GetUsers( string SystemID ) {
return RegistrationTables.SystemUsersTable == null ? null :
RegistrationTables.SystemUsersTable.AsEnumerable(
).Where( Row => Row.RowState != DataRowState.Deleted && Row.Field<string>( "Computer_ID" ) == SystemID
).Select( ( Row ) => new RegistrationEntries.User( Row.Field<string>( "User_ID" ) )
).OrderBy( User => User.UserName ).ToList( );
}
在包含此组合框的控件中,我有一系列显示用户信息的文本框。目前完成的方式尚未经过测试,但我知道它会起作用:
this.cbxUsers.SelectionChanged += ( cbxS, cbxE ) => {
RegistrationEntries.User User = ( cbxS as ComboBox ).SelectedValue as RegistrationEntries.User;
this.tbxBuyerName.Text = User.UserName;
this.tbxBuyerEmail.Text = User.UserPhone;
this.tbxBuyerPhone.Text = User.UserPhone;
this.tbxBuyerCompany.Text = User.UserCompany;
};
但是,对我来说理想的是能够实现某种方法,将每个文本框双向绑定到包含用户的 ComboBox SelectedValue
的不同属性,这样每个从组合框中选择新用户时,文本框将填充相关值,每次更改其中一个文本框时,用户将更新其各自的值。
这可能吗?这还合理吗?如果没有,是否有一些我忽略的更简单的替代方案?
创建一个 class 来包含您的用户和 CurrentUser,如下所示:
public class UsersViewModel : INotifyPropertyChanged
{
private User _currentUser = null;
public UsersViewModel(IEnumerable<User> users)
{
this.Users = new ObservableCollection<User>(users);
}
public event PropertyChangedEventHandler PropertyChanged;
public User CurrentUser
{
get
{
return this._currentUser;
}
set
{
this._currentUser = value;
this.OnPropertyChanged("CurrentUser");
}
}
public ObservableCollection<User> Users { get; protected set; }
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
创建一些 Xaml 如下所示:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ComboBox Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Users}" SelectedValue="{Binding Path=CurrentUser, Mode=TwoWay}" DisplayMemberPath="UserName" />
<Label Grid.Column="0" Grid.Row="1">UserName</Label>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=CurrentUser.UserName, Mode=TwoWay}" />
<Label Grid.Column="0" Grid.Row="2">Email</Label>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=CurrentUser.UserEmail, Mode=TwoWay}" />
<Label Grid.Column="0" Grid.Row="3">Phone</Label>
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding Path=CurrentUser.UserPhone, Mode=TwoWay}" />
</Grid>
</Window>
然后将 Window 或 UserControl 的 DataContext 设置为 UsersViewModel 的实例。
我有一个数据 table,其中保存了用户信息列表。
为了简单地与 table 交互,我创建了一个 class,它接受用户 ID(table 的主键),并查询 table 检索用户信息:
public class User {
/// <summary>
/// Initialize a new User Object.
/// </summary>
/// <param name="ID">User UUID</param>
public User( string ID ) {
this.UserID = ID;
}
/// <summary>
/// Get User UUID
/// </summary>
public string UserID { get; private set; }
/// <summary>
/// Get or Set User Name
/// </summary>
public string UserName {
get { return this.Get( "User_Name" ); }
set { this.Set( "User_Name", value ); }
}
/// <summary>
/// Get or Set User Company
/// </summary>
public string UserCompany {
get { return this.Get( "User_Company" ); }
set { this.Set( "User_Company", value ); }
}
/// <summary>
/// Get or Set User Email
/// </summary>
public string UserEmail {
get { return this.Get( "User_Email" ); }
set { this.Set( "User_Email", value ); }
}
/// <summary>
/// Get or Set User Phone Number
/// </summary>
public string UserPhone {
get { return this.Get( "User_Phone" ); }
set { this.Set( "User_Phone", value ); }
}
/// <summary>
/// Get string representation of this User.
/// </summary>
/// <returns>User Name</returns>
public override string ToString( ) { return this.UserName; }
private string Get( string fromField ) {
return RegistrationTables.UsersTable == null ? "USER TABLE EMPTY" :
RegistrationEntries.Get<string>( RegistrationTables.UsersTable, "User_ID", this.UserID, fromField );
}
private void Set( string toField, string value ) {
if ( RegistrationTables.UsersTable == null )
return;
RegistrationEntries.Set( RegistrationTables.UsersTable, "User_ID", this.UserID, toField, value );
}
}
现在我还有一个 ComboBox,我将其数据源设置为用户列表:
this.cbxUsers.SetBinding( ItemsControl.ItemsSourceProperty, new Binding( ) { Source = RegistrationTables.GetUsers( this.SystemID ) } );
public static List<RegistrationEntries.User> GetUsers( string SystemID ) {
return RegistrationTables.SystemUsersTable == null ? null :
RegistrationTables.SystemUsersTable.AsEnumerable(
).Where( Row => Row.RowState != DataRowState.Deleted && Row.Field<string>( "Computer_ID" ) == SystemID
).Select( ( Row ) => new RegistrationEntries.User( Row.Field<string>( "User_ID" ) )
).OrderBy( User => User.UserName ).ToList( );
}
在包含此组合框的控件中,我有一系列显示用户信息的文本框。目前完成的方式尚未经过测试,但我知道它会起作用:
this.cbxUsers.SelectionChanged += ( cbxS, cbxE ) => {
RegistrationEntries.User User = ( cbxS as ComboBox ).SelectedValue as RegistrationEntries.User;
this.tbxBuyerName.Text = User.UserName;
this.tbxBuyerEmail.Text = User.UserPhone;
this.tbxBuyerPhone.Text = User.UserPhone;
this.tbxBuyerCompany.Text = User.UserCompany;
};
但是,对我来说理想的是能够实现某种方法,将每个文本框双向绑定到包含用户的 ComboBox SelectedValue
的不同属性,这样每个从组合框中选择新用户时,文本框将填充相关值,每次更改其中一个文本框时,用户将更新其各自的值。
这可能吗?这还合理吗?如果没有,是否有一些我忽略的更简单的替代方案?
创建一个 class 来包含您的用户和 CurrentUser,如下所示:
public class UsersViewModel : INotifyPropertyChanged
{
private User _currentUser = null;
public UsersViewModel(IEnumerable<User> users)
{
this.Users = new ObservableCollection<User>(users);
}
public event PropertyChangedEventHandler PropertyChanged;
public User CurrentUser
{
get
{
return this._currentUser;
}
set
{
this._currentUser = value;
this.OnPropertyChanged("CurrentUser");
}
}
public ObservableCollection<User> Users { get; protected set; }
protected virtual void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
创建一些 Xaml 如下所示:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<ComboBox Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="0" ItemsSource="{Binding Users}" SelectedValue="{Binding Path=CurrentUser, Mode=TwoWay}" DisplayMemberPath="UserName" />
<Label Grid.Column="0" Grid.Row="1">UserName</Label>
<TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=CurrentUser.UserName, Mode=TwoWay}" />
<Label Grid.Column="0" Grid.Row="2">Email</Label>
<TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=CurrentUser.UserEmail, Mode=TwoWay}" />
<Label Grid.Column="0" Grid.Row="3">Phone</Label>
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding Path=CurrentUser.UserPhone, Mode=TwoWay}" />
</Grid>
</Window>
然后将 Window 或 UserControl 的 DataContext 设置为 UsersViewModel 的实例。