wpf Combobox绑定到多账户信息

发布时间 2023-06-04 19:38:33作者: trykle

本示例的注意点:
CurrentAccount 不要绑定到 Combobox 的 SelectedItem 上,会被置空,置空后无法回传用户输入的数据
在关键操作处对 CurrentAccount 进行克隆,使其区别于列表内的引用对象

ui

<StackPanel Margin="5">
    <ComboBox
        Margin="4"
        DisplayMemberPath="UserName"
        IsEditable="True"
        ItemsSource="{Binding Accounts}"
        SelectionChanged="{t:Action SelectAccount(@s.SelectedItem)}"
        Text="{Binding CurrentAccount.UserName}" />
    <TextBox Margin="4" Text="{Binding CurrentAccount.Password}" />
    <Button
        Margin="4"
        Click="{t:Action Login()}"
        Content="登录" />
</StackPanel>

model

/// <summary>
/// 账户model
/// </summary>
public class Account
{
    public string UserName { get; set; }
    public string Password { get; set; }

    public Account()
    {

    }

    public Account(string userName, string password)
    {
        UserName = userName;
        Password = password;
    }
    public override string ToString()
    {
        return $"{UserName},{Password}";
    }
}

public class MainWindowViewModel : ViewModelBase
{
    public ObservableCollection<Account> Accounts
    {
        get => GetProperty<ObservableCollection<Account>>();
        set => SetProperty(value);
    }

    /// <summary>
    /// 当前账户,不要绑定到Combobox的SelectedItem上,会被置空
    /// .UserName和.Password分别绑定到文字上,可以让当前用户输入的文字进行回传
    /// </summary>
    public Account CurrentAccount { get => GetProperty<Account>(); set => SetProperty(value); }


    private Account Clone(Account account)
    {
        return new Account(account.UserName, account.Password);
    }

    public MainWindowViewModel()
    {
        //从本地读取配置
        Accounts = new ObservableCollection<Account>()
        {
            new Account("user1","pwd1"),
            new Account("user2","pwd2"),
        };
        CurrentAccount = Clone(Accounts[0]);
    }

    /// <summary>
    /// 绑定到 Combobox的SelectionChanged事件,
    /// 并传递当前选择的item过来
    /// </summary>
    /// <param name="account"></param>
    public void SelectAccount(Account account)
    {
        //为空的情况一般为在combobox上输入后,得到一个列表里面没有的数据 
        if (account != null)
        {
            //克隆一个,让当前输入不影响列表里的对象
            CurrentAccount = Clone(account);
        }
    }

    public void Login()
    {
        if (CurrentAccount == null)
        {
            CurrentAccount = new Account();
        }
        if (string.IsNullOrEmpty(CurrentAccount.UserName) || string.IsNullOrEmpty(CurrentAccount.Password))
        {
            MessageBox.Show($"账号或密码为空");
            return;
        }

        //将当前账户保存到列表内
        //先检查是否存在
        var hasCurrent = Accounts.Where(x => x.UserName == CurrentAccount.UserName).Count() > 0;
        //不存在则添加,添加的是克隆对象
        if (!hasCurrent) { Accounts.Add(Clone(CurrentAccount)); }
        //将对象序列化到本地保存,删除的逻辑也是类型从列表中查询删除

        //登录逻辑
        MessageBox.Show($"当前账号:{CurrentAccount}");

    }
}