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