C#.NET4 WPF - 从字符串中设置combobox selecteditem

时间:2010-07-19 11:22:55

标签: c# wpf

我是C#和.net平台世界的新人,所以请对我很轻松。 这个论坛帮助我解决了我在做项目时遇到的一些问题,但我现在已经坚持了几天。 我想要实现的是通过向其传递一个字符串来设置组合框的选择项。 场景是: 我有一个数据表,我将组合的itemssource设置为该datatable.DefaultView。 另外我设置了组合的DisplayMemberPath,到目前为止一切正常,项目显示在组合框中。 除此之外我还有一个字符串,其中包含了我在组合框内的一些值。 所以我试图像这样设置组合的选择项:

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属性。 我不知道这是一个很好的编程实践,但这正是我所需要的。

2 个答案:

答案 0 :(得分:3)

你做错了什么。

这是一个显示此项目的演示应用程序(该项目应命名为“StringCombo”)。

<Window
x:Class="StringCombo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
ResizeMode="CanResize">
<Window.DataContext>
    <ViewModel
        xmlns="clr-namespace:StringCombo" />
</Window.DataContext>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <ComboBox
        Name="OldeFashonedCombo" />
    <Button
        Grid.Column="1"
        Content="Select Olde Waye"
        Click="Button_Click" />
    <ComboBox
        Grid.Row="1"
        ItemsSource="{Binding Strings}"
        SelectedItem="{Binding SelectedString}" />
    <Button
        Grid.Row="1"
        Grid.Column="1"
        Content="Select New Way"
        Command="{Binding SelectString}" />
</Grid>
</Window>

我们有两个连击和两个按钮。一个使用旧的winforms代码隐藏方法来操作组合,另一个使用新的MVVM模式。

在这两种情况下,用户单击按钮,它会设置组合的SelectedValue,以及ui上的组合更新。

这是代码隐藏版本:

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";
}

注意我没有使用“Two”的相同“实例”;在.NET平台中,没有必要将字符串“interned”或相同的实例自动重用。 object.ReferenceEquals("Two","Two")永远是真的。

因此,我将一些字符串添加到Items集合中,当单击该按钮时,我将SelectedItem设置为“Two”。 SelectedItem是应该选择的Items集合中的实际实例。 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();
    }
}

同样,由于实习,我不必使用字符串的相同“实例”。要查看ViewModel如何连接到UI,请检查ComboBox和Button上的绑定(如果您尚未查看它,我强烈建议放弃MVVM的代码隐藏。可能需要花费更多精力来计算它出来,但从长远来看,它会更好。)

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

答案 1 :(得分:-1)

我认为使用findby会像

那样工作
combo.ClearSelection();
combo.Items.FindByValue(mystring).Selected = true;