2010-07-19 4 views
2

Im tout nouveau dans le monde de la plate-forme C# et. NET, alors s'il vous plaît soyez facile sur moi. Ce forum m'a aidé dans quelques problèmes que j'ai rencontrés pendant que je faisais mon projet, mais je suis maintenant coincé dessus pendant quelques jours. Ce que j'essaye de réaliser est de placer le selecteditem d'un combobox en lui passant une chaîne. Le scénario est: J'ai un datatable et je mets la source d'éléments du combo à cette datatable.DefaultView. Aussi, je définis le DisplayMemberPath du combo, et pour l'instant tout va bien, les éléments apparaissent dans la liste déroulante. A côté de cela, j'ai une chaîne avec une certaine valeur que j'ai à l'intérieur de la combobox aussi. Donc, je suis en train de régler la SelectedItem du combo comme celui-ci:C# .NET4 WPF - Set combobox selecteditem à partir d'une chaîne

combo.SelectedItem = mystring; 

Comme vous pouvez le deviner, cela ne fonctionne pas. Étrangement, quand je fais ceci:

combo.Items.Add(mystring); 
combo.SelectedItem = mystring; 

Cela fonctionne. Donc c'est pourquoi je suis confus!

EDIT:

Je viens de trouver la solution:

combo.ItemsSource = datatable.DefaultView; 
combo.DisplayMemberPath = "yourpath"; 
combo.SelectedValuePath = "yourpath"; 
combo.SelectedValue = mystring; 

Donc, l'astuce était de mettre la SelectedValuePath et les propriétés selectedValue. Je ne sais pas est-ce une bonne pratique de programmation, mais cela fait exactement ce dont j'avais besoin.

Répondre

-1

Je pense en utilisant le findby fonctionnera donc quelque chose comme

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

Je ne sais pas est-ce ma faute à certains égards, ou est peut-être quelque chose de nouveau dans. Net4 mais il n'y a pas de méthode ClearSelection ni FindByValue pour une zone de liste déroulante. J'ai trouvé quelques exemples comme celui-ci sur le forum mais ils n'ont pas fonctionné, c'est pourquoi j'ai posté cette question. – Doktor83

+0

Ahh désolé, c'est étrange. Est-ce un DropDownList avec lequel vous travaillez? Ou quelque chose comme un ListView? Je ne peux pas trouver n'importe quel suggérer ClearSelection ou FindByValue a été abandonné pour DropDownList. –

+0

c'est juste un simple contrôle Combobox que j'ai tiré de la boîte à outils, donc je suppose que c'est une simple liste déroulante. – Doktor83

3

Vous faites quelque chose de mal.

Voici une application de démonstration qui montre cela (le projet devrait être nommé "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> 

Nous avons deux combos et deux boutons. L'un utilise l'ancienne méthode winforms de codebehind pour manipuler le combo, et l'autre utilise le nouveau pattern MVVM.

Dans les deux scénarios, l'utilisateur clique sur le bouton, il définit la valeur SelectedValue du combo et les mises à jour de la combo sur l'interface utilisateur.

est ici la version codebehind:

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

Avis Je ne suis pas en utilisant le même "instance" de "deux"; il n'y a pas besoin de chaînes "internées", ou la même instance est automatiquement réutilisée, dans la plate-forme .NET. object.ReferenceEquals("Two","Two") est toujours vrai. Par conséquent, j'ajoute des chaînes à la collection Items, et lorsque le bouton est cliqué, je définis l'élément SelectedItem sur "Two". SelectedItem est l'instance réelle dans la collection Items qui doit être sélectionnée. SelectedValue est la valeur d'affichage; vous pouvez choisir par cet IIRC, mais je ne ferais pas cela comme une bonne pratique.

Voici la version 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(); 
    } 
} 

Encore une fois, à cause d'interner, je ne dois pas utiliser le même « instance » de la chaîne.Pour voir comment le ViewModel se connecte à l'interface utilisateur, vérifiez les liens sur le ComboBox et le bouton (Si vous ne l'avez pas encore examiné, je vous suggère fortement d'abandonner le codebehind pour MVVM. dehors, mais c'est BEAUCOUP mieux à long terme).

ANYHOW, Si vous exécutez cette application, vous verrez que les deux versions fonctionnent comme prévu. Lorsque vous cliquez sur le bouton, la zone de liste déroulante est mise à jour correctement. Cela suggère que votre code est erroné d'une autre manière. Je ne sais pas quoi, car vous ne nous avez pas donné suffisamment de détails pour le déterminer. Mais si vous exécutez l'exemple et le comparez étroitement avec votre code, vous pourriez être en mesure de comprendre cela.

+0

[Voici le projet sur mon SkyDrive] (http://cid-f8be9de57b85cc35.office.live.com/self.aspx/Public/StringCombo/StringCombo.zip) – Will

+0

merci, cela fonctionne vraiment. – Doktor83