WPF 组合框绑定和 SelectedValue 与 SelectedValuePath

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43009152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 14:03:25  来源:igfitidea点击:

WPF Combobox binding and SelectedValue with SelectedValuePath

c#wpfmvvmselectedvalue

提问by Cass

I am really struggling with data binding and the MVVM Methodology, though I like the concept I am just struggling. I have created a WPF for that has multiple comboboxes and a button. The first combobox will list database instance names. the remaining comboboxes will be populated after the button is clicked. Since I am having issues with the first, database instances, combobox I will only show my code for that. When the application starts up the combobox is loaded and the first item is selected, as expected. The issue is when I select a new name my method that I expect to get called does not. Can someone help me to understand why my method public DBInstance SelectedDBInstanceis not getting executed when I have this in my XAML, SelectedValue="{Binding SelectedDBInstance, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}?

我真的在数据绑定和 MVVM 方法论方面苦苦挣扎,尽管我喜欢我只是在苦苦挣扎的概念。我为它创建了一个 WPF,它有多个组合框和一个按钮。第一个组合框将列出数据库实例名称。单击按钮后,将填充剩余的组合框。由于我遇到了第一个数据库实例的问题,组合框我将只显示我的代码。当应用程序启动时,组合框被加载并按预期选择了第一个项目。问题是当我选择一个新名称时,我希望调用的方法没有。有人能帮我理解为什么我的方法public DBInstance SelectedDBInstance在我的 XAML 中没有被执行SelectedValue="{Binding SelectedDBInstance, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}吗?

Here is my XAML for the database instances combobox. One question I have here is the "value" fpr SelectedValuePath, if I change it to say "DBInstanceName" it does not work.

这是我的数据库实例组合框的 XAML。我在这里遇到的一个问题是“值”fpr SelectedValuePath,如果我将其更改为“DBInstanceName”,则它不起作用。

 <ComboBox x:Name="cbxRLFDBInstances" ItemsSource="{Binding DBInstances}" 
                  SelectedValue="{Binding SelectedDBInstance, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
                  SelectedValuePath="value" DisplayMemberPath="DBInstanceName"/>

Here is my ViewModel Code:

这是我的 ViewModel 代码:

namespace DatabaseTest.ViewModel
{

class RLFDatabaseTableViewModel : INotifyPropertyChanged
{
    Utilities dbtUtilities = new Utilities();


    public RelayCommand LoadDBInfoCommand
    {
        get;
        set;
    }


    public RLFDatabaseTableViewModel()
    {
        LoadDBInstances();

        LoadDBInfoCommand = new RelayCommand(LoadDBInfo);
    }


    public ObservableCollection<DBInstance> DBInstances
    {
        get;
        set;
    }


    public void LoadDBInstances()
    {
        ObservableCollection<DBInstance> dbInstances = new ObservableCollection<DBInstance>();
        DataTable dt = SmoApplication.EnumAvailableSqlServers(false);

        dbInstances.Add(new DBInstance { DBInstanceName = "fal-conversion\mun2012ci" });
        dbInstances.Add(new DBInstance { DBInstanceName = "fal-conversion\mun2014ci" });

        if (dt.Rows.Count > 0)
        {
            foreach (DataRow dr in dt.Rows)
            {
                dbInstances.Add(new DBInstance { DBInstanceName = dr["Name"].ToString() });
            }
        }

        DBInstances = dbInstances;

    }


    private DBInstance _selectedDBInstance;


    public DBInstance SelectedDBInstance
    {
        get
        {
            return _selectedDBInstance;
        }

        set
        {
            _selectedDBInstance = value;
            RaisePropertyChanged("SelectedDBInstance");
            //ClearComboBoxes();

        }
    }
}
}

Here is my Model code. When I step through the code this method, public string DBInstanceName, gets executed multiple time. I do not know why and it is seems wasteful to me.

这是我的模型代码。当我逐步public string DBInstanceName执行此方法的代码时,, 会被多次执行。我不知道为什么,这对我来说似乎很浪费。

namespace DatabaseTest.Model
{
public class RLFDatabaseTableModel { }


public class DBInstance : INotifyPropertyChanged
{
    private string strDBInstance;


    public override string ToString()
    {
        return strDBInstance;
    }


    public string DBInstanceName
    {
        get
        {
            return strDBInstance;
        }

        set
        {
            if (strDBInstance != value)
            {
                strDBInstance = value;
                RaisePropertyChanged("DBInstanceName");
            }
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

回答by mm8

You should bind the SelectedItemproperty of the ComboBoxto the SelectedDBInstanceproperty and get rid of the SelectedValuePath:

您应该将 的SelectedItem属性绑定ComboBox到该SelectedDBInstance属性并去掉SelectedValuePath

<ComboBox x:Name="cbxRLFDBInstances" ItemsSource="{Binding DBInstances}" 
              SelectedItem="{Binding SelectedDBInstance, UpdateSourceTrigger=PropertyChanged}" 
              DisplayMemberPath="DBInstanceName"/>

The SelectedValuePathproperty is only used when you want to bind to a source property that is not of the same type as the item in the ItemsSourcecollection.

SelectedValuePath属性仅在您想要绑定到与ItemsSource集合中的项目不同类型的源属性时使用。

To select an item initially you should set the SelectedDBInstanceproperty to an item that is present in the DBInstancescollection:

要最初选择一个项目,您应该将SelectedDBInstance属性设置为DBInstances集合中存在的项目:

public RLFDatabaseTableViewModel()
{
    LoadDBInstances();
    LoadDBInfoCommand = new RelayCommand(LoadDBInfo);
    SelectedDBInstance = DBInstances[0]; //selected the first item
}