2017-08-02 2 views
0

Ich habe eine Situation mit einem ListBox-Steuerelement. In der Artikelvorlage befindet sich eine Schaltfläche. Wenn ich auf die Schaltfläche klicke, die ich in der ListBox auswählen möchte, um zu dem Element zu wechseln, in dem sich die Schaltfläche befindet. Im Moment kann ich das ausgewählte Element ändern, indem ich auf eine andere Stelle in der Elementvorlage klicke, aber das funktioniert nicht, wenn ich wähle die Taste. Um den letzten Satz für einen Kommentator zu verdeutlichen, ändert sich das SelectedItem wie erwartet, wenn man in die Elementvorlage klickt, die nicht die Schaltfläche ist. Wenn Sie auf die Schaltfläche innerhalb der Objektvorlage klicken, ändert sich das SelectedItem nicht.Schaltfläche innerhalb der ListBox ItemTemplate nicht Element

Weitere Informationen: Ich benutze MVVM und die Schaltfläche hat einen Befehl in einem Ansichtsmodell angefügt. Jede Lösung müsste es ermöglichen, dass dies weiterhin funktioniert.

Die ListBox ist mit ItemSource verknüpft, und das SelectedItem der ListBox ist an eine Eigenschaft im Ansichtsmodell gebunden.

Wenn es einen festgelegten Weg gibt, konnte ich es bisher nicht finden.

Ich bin mit C# und Visual Studio 2010.

Dank.

+1

Ein bisschen von XAML und cs wäre wirklich hilfreich. * "Das funktioniert nicht, wenn ich den Knopf" * - wie genau funktioniert es nicht? – Sinatr

Antwort

1

Wenn Sie ToggleButton verwenden und die IsChecked an die ListBoxItemIsSelected Eigenschaft binden können, dann wird es in Ordnung sein.
Grund, weil Ihre ListBoxItem nicht ausgewählt ist, weil die Schaltfläche MouseDown Ereignis behandelt wird, so dass die ListBoxItem der Klick nicht bewusst. Erstellen Sie in Ihrer Schaltfläche einen Ereignishandler für Click, und legen Sie e.Handled = false; fest.

+0

Es tut mir leid, ich verstehe nicht. Sind diese beiden Dinge, die du sagst, beide notwendig? – TheFaithfulLearner

+0

@TheFaithfulLearner Keine Sorge, was ich meinte ist _Wenn du kannst_, bedeutet das, wenn du keinen 'Knopf' benutzen musst. Das würde bedeuten, dass Sie den Button einmal anklicken müssen, um ihn "anzuklicken". Aber beides ist nicht notwendig. Versuchen Sie, den Click-Event-Handler hinzuzufügen und setzen Sie einfach 'e.handled = false;' – XAMlMAX

+0

@TheFaithfulLearner Und noch eine Sache. Wenn Sie den Event-Handler setzen, stellen Sie sicher, dass er in XAML vor dem Command Biding steht, damit er vor dem Befehl ausgeführt wird. – XAMlMAX

1

Ein bisschen von Ihrem Code wäre hilfreich gewesen, aber hier ist ein Dummy-Beispiel für die Auswahl einer ListBoxItem mit einem Klick auf eine Schaltfläche, durch die MVVM-Muster.

public class MyViewModel : BaseViewModel // implements INotifyPropertyChanged 
{ 
    private ICommand _myCommand; 

    public ICommand MyCommand { get {return _myCommand;} private set { _myCommand = value; OnPropertyChanged(); }} 

    private ObservableCollection<int> _myObjects; 

    public ObservableCollection<int> MyObjects { get {return _myObjects;} private set {_myObjects = value; OnPropertyChanged();}} 

    private int _mySelectedObject; 

    public int MySelectedObject { get {return _mySelectedObject;} set {_mySelectedObject = value; OnPropertyChanged(); }} 

    public MyViewModel 
    { 
     MyCommand = new RelayCommand(SetSelectedObject); // the source code for RelayCommand may be found online. 
    } 

    private void SetSelectedObject(object obj) 
    { 
     int myInt = (int)obj; 

     MySelectedObject = myInt; 
    } 
} 

Einige XAML-Teile wurden gelöscht, um es einfach zu halten. Kopieren Sie dieses Snippet nicht einfach, passen Sie es an Ihren Code an.

<UserControl x:Name="root" DataContext="{Binding MyViewModel, Source={StaticResource Locator.MyViewModel}}"> 
    <ListBox ItemsSource="{Binding MyObjects}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel> 
        <TextBlock Text="{Binding }"/> 
        <Button Command="{Binding MyCommand, ElementName=root}" CommandParameter="{Binding }"/> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</UserControl> 

Ich habe diesen Code nicht getestet. Also könnte es einige Fehler geben. Zögern Sie nicht, darauf hinzuweisen, und ich werde meinen Code aktualisieren.

EDIT: Hier ist der Quellcode für meine RelayCommand Implementierung (von Telerik modifiziert):

public class RelayCommand : ICommand 
{ 
    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    private Action<object> _methodToExecute; 
    private Func<object, bool> _canExecuteEvaluator; 

    public RelayCommand(Action<object> methodToExecute, Func<object, bool> canExecuteEvaluator) 
    { 
     _methodToExecute = methodToExecute; 
     _canExecuteEvaluator = canExecuteEvaluator; 
    } 

    public RelayCommand(Action<object> methodToExecute) 
     : this(methodToExecute, null) 
    { 
    } 

    public bool CanExecute(object parameter) 
    { 
     if (_canExecuteEvaluator == null) 
     { 
      return true; 
     } 
     else 
     { 
      bool result = _canExecuteEvaluator.Invoke(parameter); 
      return result; 
     } 
    } 

    public void Execute(object parameter) 
    { 
     _umethodToExecute.Invoke(parameter); 
    } 
} 
+0

Hallo dort. Danke für die Information. Ich fing an, dies in die Praxis umzusetzen, aber als ich versuchte, MyCommand zu einem neuen RelayCommand mit dem Parameter 'SetSelectedObject' zu initialisieren. Diese Methode existiert auch und ist wie du es geschrieben hast. Der angegebene Fehler ist 'Argument 1: Konvertierung von' Methodengruppe 'in' System.Action 'nicht möglich. Ich benutze MVVM Light ... vielleicht wirkt sich das auf die Dinge aus. – TheFaithfulLearner

+0

Wenn Sie meine Lösung verwenden möchten, müssen Sie möglicherweise eine andere RelayCommand-Implementierung verwenden. Bitte beziehen Sie sich auf meinen Beitrag, ich habe ihn gerade bearbeitet. – Atlasmaybe

Verwandte Themen