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 的实例。