【问题标题】:WPF MVVM Combobox SelectionChanged/SelectedItemWPF MVVM 组合框 SelectionChanged/SelectedItem
【发布时间】:2018-05-03 00:46:45
【问题描述】:

我正在使用 MVVM 和 mySql 数据库构建 WPF 应用程序。我很难从存储在属性中的组合框中获取SelectedItem。基本上,此时,我希望 SelectedItem 显示在文本框中。这将帮助我更好地理解绑定过程,因为我还在学习。

最终,我想使用存储的值/属性作为从数据库中提取另一个值的参考。下面是一些示例代码。任何帮助将不胜感激。谢谢!

查看

        <Grid Background="AliceBlue">

        <Label Content="Street Address" HorizontalAlignment="Left" Margin="10,54,0,0" VerticalAlignment="Top" Width="87" Height="28"/>
        <Label Content="State" HorizontalAlignment="Left" Margin="10,125,0,0" VerticalAlignment="Top" Width="87" Height="22"/>


        <TextBox Name="txtStreetAddress" HorizontalAlignment="Left" Height="23" Margin="119,55,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"
                 Text="{Binding StreetAddress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                 />
        <ComboBox Name="cboState" 
              HorizontalAlignment="Left" Margin="119,125,0,0" VerticalAlignment="Top" Width="52"
              DisplayMemberPath="StateAbb"
              ItemsSource="{Binding StateAbbList}"
              SelectedItem="{Binding SelectedStateAbb, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
              />

        <TextBox HorizontalAlignment="Left" Height="23" Margin="180,124,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="59"
                 Text="{Binding SelectedStateAbb, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                 />


    </Grid>

查看模型

public class AddStreetAddressVM : ObservableObject, IPageViewModel
{

    public string Name
    {
        get
        {
            return "Add Street Address";
        }
    }

    const string dbConnectionString = @"datasource=localhost;port=3306;Initial Catalog='optest1a1';username=root;password=";

    private ICommand _cboStateAbb;

    private string _streetAddress;
    private ObservableCollection<tblStateAbb> _stateAbbList;
    private string _selectedStateAbb;
    private int _selectedStateNum;

    public ICommand CboStateAbb
    {
        get
        {
            if (_cboStateAbb == null)
            {
                _cboStateAbb = new RelayCommand(param => this.fillStateAbb(), null);
            }

            return _cboStateAbb;
        }
    }

    public string StreetAddress
    {
        get { return _streetAddress; }
        set { SetProperty(ref _streetAddress, value, () => StreetAddress); }
    }

    public ObservableCollection<tblStateAbb> StateAbbList
    {
        get { return _stateAbbList; }
        set
        {
            SetProperty(ref _stateAbbList, value, () => StateAbbList);
        }
    }

    public string SelectedStateAbb
    {
        get { return _selectedStateAbb; }
        set
        {
            SetProperty(ref _selectedStateAbb, value, () => SelectedStateAbb);
            //if (_selectedStateAbb != null)
            //{
            //    GetStateNum();
            //}

            //_selectedStateAbb = value;
        }
    }

    public int SelectedStateNum
    {
        get { return _selectedStateNum; }
        set { SetProperty(ref _selectedStateNum, value, () => SelectedStateNum); }
    }

    public AddStreetAddressVM() : base()
    {
        StateAbbList = new ObservableCollection<tblStateAbb>();
        fillStateAbb();
    }

    private void fillStateAbb()
    {
        using (MySqlConnection con = new MySqlConnection(dbConnectionString))
        {
            StateAbbList = new ObservableCollection<tblStateAbb>();
            con.Open();
            string Query = "SELECT * FROM tbl_states";
            MySqlCommand createCommand = new MySqlCommand(Query, con);
            MySqlDataReader dr = createCommand.ExecuteReader();
            int count = 1;
            while (dr.Read())
            {
                string StateAbb = dr.GetString(2);
                tblStateAbb stateabb = new tblStateAbb(count, StateAbb);
                StateAbbList.Add(stateabb);
                count++;
            }
            con.Close();
        }
    }

    private void GetStateNum()
    {
        using (MySqlConnection con = new MySqlConnection(dbConnectionString))
        {
            con.Open();
            string Query = "SELECT State_Num FROM tbl_states WHERE State_Abb='" + SelectedStateAbb + "' ";
            MySqlCommand createCommand = new MySqlCommand(Query, con);
            MySqlDataReader dr = createCommand.ExecuteReader();
            int count = 1;
            while (dr.Read())
            {
                int StateNum = dr.GetInt32(1);
                StateNum = SelectedStateNum;
            }
            con.Close();
        }

    }

}

模型 - 州缩写

public class tblStateAbb : ObservableObject
{
    private Int32 _count;
    private String _stateAbb;
    private Int32 _stateNum;
    private ObservableCollection<tblStateAbb> _tblStateAbb;

    public Int32 Count
    {
        get { return _count; }
        set { SetProperty(ref _count, value, () => Count); }
    }

    public String StateAbb
    {
        get { return _stateAbb; }
        set { SetProperty(ref _stateAbb, value, () => StateAbb); }
    }

    public Int32 StateNum
    {
        get { return _stateNum; }
        set { SetProperty(ref _stateNum, value, () => StateNum); }
    }

    public ObservableCollection<tblStateAbb> StateAbbList
    {
        get { return _tblStateAbb; }
        set { SetProperty(ref _tblStateAbb, value, () => StateAbbList); }
    }

    public tblStateAbb() : base()
    {
        Count = 0;
        StateAbb = "";
        StateAbbList = new ObservableCollection<tblStateAbb>();
    }

    public tblStateAbb(int count, string stateabb) : base()
    {
        Count = count;
        StateAbb = stateabb;
        StateAbbList = new ObservableCollection<tblStateAbb>();
    }

    public tblStateAbb(int count, string stateabb, int statenum) : base()
    {
        Count = count;
        StateAbb = stateabb;
        StateNum = statenum;
        StateAbbList = new ObservableCollection<tblStateAbb>();
    }

}

可观察对象(INotifyPropertyChange)

public abstract class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propName)
    {
        Debug.Assert(GetType().GetProperty(propName) != null);

        var pc = PropertyChanged;
        if (pc != null)
        {
            pc(this, new PropertyChangedEventArgs(propName));
        }
    }

    protected bool SetProperty<T>(ref T field, T value, string propName)
    {
        if (!EqualityComparer<T>.Default.Equals(field, value))
        {
            field = value;
            OnPropertyChanged(propName);
            return true;
        }

        return false;
    }

    protected bool SetProperty<T>(ref T field, T value, Expression<Func<T>> expr)
    {
        if (!EqualityComparer<T>.Default.Equals(field, value))
        {
            field = value;
            var lambda = (LambdaExpression)expr;
            MemberExpression memberExpr;

            if (lambda.Body is UnaryExpression)
            {
                var unaryExpr = (UnaryExpression)lambda.Body;
                memberExpr = (MemberExpression)unaryExpr.Operand;
            }
            else
            {
                memberExpr = (MemberExpression)lambda.Body;
            }

            OnPropertyChanged(memberExpr.Member.Name);
            return true;
        }

        return false;
    }
}

中继命令

    public class RelayCommand : ICommand
{
    private Action<object> execute;
    private Func<object, bool> canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return this.canExecute == null || this.canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        this.execute(parameter);
    }
}

【问题讨论】:

  • 您认为您需要帮助并且要求我们阅读您发布的所有代码是否公平?请缩小问题范围,只发布您的代码的那部分。
  • 为什么不直接阅读您感兴趣的部分?如果您认为我应该只发布视图,那么只阅读视图并忽略其他所有内容。没有?
  • 公平地说,我对阅读任何内容都不感兴趣。老实说,大多数其他人也不感兴趣。我想说的是,你需要在你的问题上付出一些努力,让它尽可能简单,这样人们才会帮助你。现在,这并不容易。这有意义吗?
  • 试试这个问题...忽略上面的所有代码,除了 View 和 ViewModel (我假设你需要一些东西):“我很难从存储的 ComboBox 中获取 SelectedItem一个属性。当我从 ComboBox 中选择一个状态时,我得到的只是“OnPoint2a1.Models.tblStateAbb”作为 SelectedStateAbb。任何帮助将不胜感激。”
  • 我觉得public string SelectedStateAbb这个属性应该是public tblStateAbb SelectedStateAbb

标签: c# mysql wpf mvvm combobox


【解决方案1】:

由于SelectedStateAbbstring,您应该将ComboBoxSelectedValuePath 属性设置为“StateAbb”并将SelectedValue 属性绑定到SelectedStateAbb

<ComboBox Name="cboState" 
        HorizontalAlignment="Left" Margin="119,125,0,0" VerticalAlignment="Top" Width="52"
        DisplayMemberPath="StateAbb"
        SelectedValuePath="StateAbb"
        ItemsSource="{Binding StateAbbList}"
        SelectedValue="{Binding SelectedStateAbb, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

<TextBox HorizontalAlignment="Left" Height="23" Margin="180,124,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="59"
         Text="{Binding SelectedStateAbb, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

【讨论】:

  • 这很好用。 CodingYoshi 和 Roger Leblanc 的答案(在原始 cmets 中)也有效。非常感谢您提供的所有帮助和意见!以后我会尽量让我的问题更简洁。干杯!