C# 带参数的按钮绑定的WPF MVVM代码

C# 带参数的按钮绑定的WPF MVVM代码,c#,button,mvvm,combobox,binding,C#,Button,Mvvm,Combobox,Binding,我有一个WPF应用程序,它有多个组合框和按钮。我正在用这个应用程序学习MVVM模型。第一个组合框将显示数据库实例的列表。这是在应用程序开始时完成的。这个很好用 数据库实例组合框旁边有一个按钮对象。当用户单击此按钮时,我需要获取数据库实例组合框的内容,并在调用中使用它来获取该实例中的所有数据库。我正在使用RelayCommand(ICommand)执行操作。按钮的操作正在正确设置。我在DBInstance类中有一个方法SelectedDatabase,但当我单击按钮时,它是空的 在下面的LoadD

我有一个WPF应用程序,它有多个组合框和按钮。我正在用这个应用程序学习MVVM模型。第一个组合框将显示数据库实例的列表。这是在应用程序开始时完成的。这个很好用

数据库实例组合框旁边有一个按钮对象。当用户单击此按钮时,我需要获取数据库实例组合框的内容,并在调用中使用它来获取该实例中的所有数据库。我正在使用RelayCommand(ICommand)执行操作。按钮的操作正在正确设置。我在DBInstance类中有一个方法SelectedDatabase,但当我单击按钮时,它是空的

在下面的LoadDBInfo方法中,selectedItem参数为null

这是我的XAML:

<ComboBox x:Name="cbxRLFDBInstances" ItemsSource="{Binding DBInstances}" 
                  SelectedValue="{Binding SelectedDBInstance}" SelectedValuePath="value" 
                  HorizontalAlignment="Left" Height="28" Margin="189,87,0,0" VerticalAlignment="Top" 
                  Width="250" FontFamily="Arial" FontSize="14.667" 
                  IsEditable="True"/>
        <Button x:Name="btnRLFDBLoadDBInfo" Content="Load DB Info" Command="{Binding LoadDBInfoCommand}" 
                CommandParameter="{Binding SelectedDBInstance}"  HorizontalAlignment="Left" Height="26" Margin="475,89,0,0" VerticalAlignment="Top" 
                Width="101" FontFamily="Arial" FontSize="14.667" Background="#FFE8F9FF" 
                ToolTip="Click here after choosing or typing in the datbase instance.  This will populate the database list."/>
        <ComboBox x:Name="cbxRLFDBName" HorizontalAlignment="Left" Height="28" Margin="189,132,0,0" 
                  ItemsSource="{Binding DBDatabases}" SelectedValue="{Binding SelectedDBDatabase}" 
                  SelectedValuePath="value" VerticalAlignment="Top" Width="250" FontFamily="Arial" 
                  FontSize="14.667" IsEditable="True" IsReadOnly="True"
                  ToolTip="Once a database is choosen the table list will automatically be populated."/>
编辑:这是我加载第二个组合框cbxRLFDBName的代码,DBDatabase有值,但没有加载组合框

public void LoadDatabases(string strDBInstanceName)
    {
        string strQuery;
        IList<DBDatabase> dbDatabases = new List<DBDatabase>();
        SqlConnection sqlUtilDBConn = null;


        try
        {
            if (sqlUtilDBConn != null)
            {
                sqlUtilDBConn.Close();
            }

            sqlUtilDBConn = dbtUtilities.LoginToDatabase(strDBInstanceName, "master");

            strQuery = "select name from sys.databases order by 1";

            using (SqlCommand sqlCmd = new SqlCommand(strQuery, sqlUtilDBConn))
            {
                SqlDataReader sqlDataRead = sqlCmd.ExecuteReader();

                while (sqlDataRead.Read())
                {
                    string strDBNme = sqlDataRead.GetString(0);

                    dbDatabases.Add(new DBDatabase { DBDatabaseName = strDBNme });
                }

                sqlDataRead.Close();
                sqlCmd.Dispose();
            }
        }
        catch (Exception exQuery)
        {
            string strMsg;


            strMsg = "GetNumRows: Error, '" + exQuery.Message + "', has occurred.";
            System.Windows.MessageBox.Show(strMsg);
        }

        DBDatabases = dbDatabases;
}
公共void加载数据库(字符串strDBInstanceName)
{
字符串strQuery;
IList dbDatabases=new List();
SqlConnection sqlUtilDBConn=null;
尝试
{
如果(sqlUtilDBConn!=null)
{
sqlUtilDBConn.Close();
}
sqlUtilDBConn=dbtUtilities.LoginToDatabase(strDBInstanceName,“master”);
strQuery=“按1从sys.databases中选择名称”;
使用(SqlCommand sqlCmd=newsqlcommand(strQuery,sqlUtilDBConn))
{
SqlDataReader sqlDataRead=sqlCmd.ExecuteReader();
while(sqlDataRead.Read())
{
string strdbname=sqlDataRead.GetString(0);
添加(新的数据库{DBDatabaseName=strDBNme});
}
sqlDataRead.Close();
sqlCmd.Dispose();
}
}
捕获(异常exQuery)
{
字符串strMsg;
strMsg=“GetNumRows:发生错误,”+exQuery.Message+”;
System.Windows.MessageBox.Show(strMsg);
}
DBDatabases=DBDatabases;
}

编辑:我删除了一些不需要的代码,希望这会更容易阅读。我的问题是,带有ItemsSource=“{Binding DBInstances}”的组合框“cbxRLFDBInstances”可以很好地加载组合框。我还有另一个组合框,“cbxRLFDBName”,带有ItemsSource=“{Binding DBDatabases}”。当我选择适当的数据库实例并单击LoadDB Info按钮时,LoadDatabases将运行,我可以看到DBDatabases中包含了所需的信息。但是,组合框没有加载,我没有失败。为什么一个ItemsSource数据绑定工作而另一个不工作?我相信我设置的类是正确的,但似乎绑定没有发生?我遗漏了什么?

您是否尝试过将命令参数作为从combobox中选择的izem传递,例如:

CommandParameter="{Binding SelectedItem,ElementName=yourComboBoxName}"

除了组合框上的
SelectedValuePath=“value”
之外,您的代码看起来很好
SelectedValuePath
指定所选项目上要绑定到
SelectedValue
的属性
SelectedBinInstance
属于
DBInstance
类型,并且
DBInstance
类未定义
value
属性,因此我认为您只需从组合框中删除
SelectedValuePath=“value”

编辑:
您需要ViewModel来实现INotifyPropertyChanged:

类RLFDatabaseTableViewModel:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私有void RaisePropertyChanged(字符串属性)
{
if(PropertyChanged!=null){
PropertyChanged(此,新PropertyChangedEventArgs(property));
}
}
//RLFDatabaseTableViewModel实现的其余部分。。。
}
然后,每次在ViewModel中更改属性值时,还需要立即调用
RaisePropertyChanged
。例如:

DBDatabases = dbDatabaseNames;
RaisePropertyChanged("DBDatabases");
这样定义属性很有帮助:

public string StringProperty
{
  get { return this.stringProperty; }
  set {
    this.stringProperty = value;
    this.RaisePropertyChanged("StringProperty");
  }
}
private string stringProperty;
那你就可以写了

this.StringProperty = "new value";
将设置新值并发送更改通知


您必须发送通知,因为视图(XAML)和ViewModel是不同的类,并且视图无法知道ViewModel上的属性已更改。如果ViewModel实现了
INotifyPropertyChanged
,WPF将通过
PropertyChanged
事件侦听属性更改,并相应地更新视图。

到底是什么问题?这对于阅读和理解来说是巨大的:当我进入LoadDBInfo方法时,传递的selectedItem对象为null。我需要获取databaseinstance组合框的内容。您的Sql连接应该为空吗<代码>SqlConnection sqlConn=null在获取selectedItem集合或获取数据库实例组合框的内容后,我可以处理else代码。由于selectedItem为null,因此代码没有意义。我认为CommandPaeameter=“{Binding SelectedDBInstance”}会触发SelectedDBInstance方法,并且会填充_SelectedDBInstance。我对装订很陌生。但我真正需要的帮助是获取数据库实例组合框中当前的值。一旦我有了这些,并希望对绑定有更好的理解,我就可以修复代码了。这给了我所需要的。非常感谢。刚找到这个out@iviica.moke--你能看一下我的最新编辑吗?对我的问题有什么想法吗?我不确定,但可能是因为您将数据库设置为列表,并且在单击按钮后初始化,列表将填充,但不会通知您的UI。尝试将该列表更改为ObservableCollection,因为它已准备好实施集合更改,并且您的UI将在集合更改时收到通知。当我绑定到集合时,我总是使用ObservableCollection。你的第一名单已经初始化了
public string StringProperty
{
  get { return this.stringProperty; }
  set {
    this.stringProperty = value;
    this.RaisePropertyChanged("StringProperty");
  }
}
private string stringProperty;
this.StringProperty = "new value";