C#.NET4 WPF-Set组合框从字符串中选择editem

C#.NET4 WPF-Set组合框从字符串中选择editem,c#,wpf,C#,Wpf,我在C#和.net平台的世界里都是新手,所以请对我放松点。 这个论坛帮助我解决了我在做项目时遇到的一些问题,但我现在坚持了几天。 我试图实现的是通过向组合框传递字符串来设置组合框的selecteditem。 情况是: 我有一个datatable,我将组合的itemssource设置为datatable.DefaultView。 此外,我还设置了组合的DisplayMemberPath,到目前为止一切正常,项目显示在组合框中。 除此之外,我还有一个字符串,该字符串在组合框中也有一些值。 因此,我尝

我在C#和.net平台的世界里都是新手,所以请对我放松点。 这个论坛帮助我解决了我在做项目时遇到的一些问题,但我现在坚持了几天。 我试图实现的是通过向组合框传递字符串来设置组合框的selecteditem。 情况是: 我有一个datatable,我将组合的itemssource设置为datatable.DefaultView。 此外,我还设置了组合的DisplayMemberPath,到目前为止一切正常,项目显示在组合框中。 除此之外,我还有一个字符串,该字符串在组合框中也有一些值。 因此,我尝试如下设置组合的selecteditem:

combo.SelectedItem = mystring;
你可以猜到,它不起作用。奇怪的是,当我这么做的时候:

combo.Items.Add(mystring);
combo.SelectedItem = mystring;
它起作用了。所以这就是我困惑的原因

编辑:

我刚刚找到了解决方案:

combo.ItemsSource = datatable.DefaultView;
combo.DisplayMemberPath = "yourpath";
combo.SelectedValuePath = "yourpath";
combo.SelectedValue = mystring;
所以诀窍是设置SelectedValuePath和SelectedValue属性。
我不知道这是不是一个好的编程实践,但这正是我所需要的。

我认为使用findby会像这样工作

combo.ClearSelection();
combo.Items.FindByValue(mystring).Selected = true;

你做错了什么

这里有一个演示应用程序显示了这一点(该项目应命名为“StringCombo”)

注意,我没有使用“两个”的相同“实例”;在.NET平台中,字符串被“插入”,或者同一实例被自动重用,因此没有必要这样做
object.ReferenceEquals(“Two”,“Two”)
始终为真

因此,我将字符串添加到Items集合中,当单击按钮时,我将SelectedItem设置为“2”。SelectedItem是应选择的
集合中的实际实例。SelectedValue为显示值;你可以通过这个IIRC来选择,但我不会把它作为最佳实践

以下是MVVM版本:

public sealed class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<string> Strings { get; private set; }

    public ICommand SelectString { get; private set; }

    public string SelectedString { get; set; }

    public ViewModel()
    {
        Strings = new ObservableCollection<string>();
        Strings.Add("Foo");
        Strings.Add("Bar");
        Strings.Add("Baz");
        SelectString = new SelectStringCommand
        {
            ExecuteCalled = SelectBar
        };
    }

    private void SelectBar()
    {
        SelectedString = "Bar";
        // bad practice in general, but this is just an example
        PropertyChanged(this, new PropertyChangedEventArgs("SelectedString"));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

/// <summary>
/// ICommands connect the UI to the view model via the commanding pattern
/// </summary>
public sealed class SelectStringCommand : ICommand
{
    public Action ExecuteCalled { get; set; }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        ExecuteCalled();
    }
}
公共密封类视图模型:INotifyPropertyChanged
{
公共ObservableCollection字符串{get;private set;}
public ICommand SelectString{get;private set;}
公共字符串SelectedString{get;set;}
公共视图模型()
{
字符串=新的ObservableCollection();
字符串。添加(“Foo”);
字符串。添加(“条”);
字符串。添加(“Baz”);
SelectString=新建SelectStringCommand
{
ExecuteCalled=选择栏
};
}
私有void SelectBar()
{
SelectedString=“Bar”;
//一般来说是不好的做法,但这只是一个例子
PropertyChanged(这是新的PropertyChangedEventArgs(“SelectedString”);
}
公共事件属性更改事件处理程序属性更改;
}
/// 
///iCommand通过命令模式将UI连接到视图模型
/// 
公共密封类SelectStringCommand:ICommand
{
公共操作执行调用{get;set;}
公共布尔CanExecute(对象参数)
{
返回true;
}
公共事件处理程序CanExecuteChanged;
public void Execute(对象参数)
{
ExecuteCalled();
}
}
同样,由于实习,我不必使用相同的字符串“实例”。要查看ViewModel如何连接到UI,请检查组合框和按钮上的绑定(如果您还没有查看,我强烈建议您放弃MVVM的codebehind。这可能需要花费更多的精力才能弄清楚,但从长远来看会更好)


无论如何,如果您运行此应用程序,您将看到两个版本都能按预期工作。单击按钮时,组合框将正确更新。这表明您的代码在其他方面是错误的。不确定是什么,因为你没有给我们足够的细节来确定。但是,如果您运行示例并将其与代码进行仔细比较,您可能会发现这一点。

我不知道这在某些方面是我的错,或者可能是.net4中的新功能,但是没有ClearSelection方法,组合框也没有FindByValue。我在论坛上找到了一些类似的例子,但它们都不起作用,所以我才发布了这个问题。啊,对了,对不起,这很奇怪。您正在使用的是下拉列表吗?或者类似ListView的东西?我似乎找不到任何提示ClearSelection或FindByValue已为DropDownList删除的内容。它只是我从工具箱中拖动的一个简单组合框控件,因此我认为它是一个简单的下拉列表。
public MainWindow()
{
    InitializeComponent();
    OldeFashonedCombo.Items.Add("One");
    OldeFashonedCombo.Items.Add("Two");
    OldeFashonedCombo.Items.Add("Three");
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    OldeFashonedCombo.SelectedItem = "Two";
}
public sealed class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<string> Strings { get; private set; }

    public ICommand SelectString { get; private set; }

    public string SelectedString { get; set; }

    public ViewModel()
    {
        Strings = new ObservableCollection<string>();
        Strings.Add("Foo");
        Strings.Add("Bar");
        Strings.Add("Baz");
        SelectString = new SelectStringCommand
        {
            ExecuteCalled = SelectBar
        };
    }

    private void SelectBar()
    {
        SelectedString = "Bar";
        // bad practice in general, but this is just an example
        PropertyChanged(this, new PropertyChangedEventArgs("SelectedString"));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

/// <summary>
/// ICommands connect the UI to the view model via the commanding pattern
/// </summary>
public sealed class SelectStringCommand : ICommand
{
    public Action ExecuteCalled { get; set; }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        ExecuteCalled();
    }
}