2016-05-09 7 views
2

Entschuldigung, wenn Sie denken, dies ist eine Duplizierung eines anderen Beitrags, aber ich habe versucht alle mögliche Lösung da draußen und ich kann es nicht funktionieren.Bind MausLeftButtonDown für ListBoxItem und Hintergrundfarbe auf PropertyChanged (MVVM, WPF)

Die Frage ist ein Zwei-Partner, aber es ist ungefähr der gleiche Code, also dachte ich, ich kann die Frage im selben Thread stellen.

Ich versuche, Bestellsystem in C#, wpf, vs2015 mit MVVM ohne (hart codierte) Kupplungen zu tun. Es gibt zwei Dinge, die ich tun muss. Zuerst muss ein Ereignis ausgelöst werden, das ich im ViewModel erfassen muss, und zweitens, wenn die Anzahl der Artikel über einem bestimmten Level liegt, sollte der Hintergrund des Listboxitems für diesen Artikel grün sein (sonst weiß/grau)

Dazu benutze ich eine ListBox und einige listBoxItems.

MainWindow.xaml (der Teil, der zählt)

 <Window x:Class="Sequence_Application_2.GUI.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
     xmlns:acb="clr-namespace:AttachedCommandBehavior;assembly=AttachedCommandBehavior" 
     mc:Ignorable="d" 
     .... 
    <Window.DataContext> 

<Grid Grid.Column="0" Margin="10"> 
       <ListBox x:Name="LstViewFlows" SelectedItem="{Binding SelectedFlow.Name}" ItemsSource="{Binding Flows.Keys}" > 
        <ListBox.ItemContainerStyle> 
         <Style TargetType="{x:Type ListBoxItem}" > 
          <Style.Triggers> 
           <DataTrigger Binding="{Binding SelectedFlow.CanDeliver, UpdateSourceTrigger=PropertyChanged}" Value="true" > 
            <Setter Property="ListBoxItem.Background" Value="DarkGreen" /> 
            <Setter Property="FontWeight" Value="Bold"/> 
           </DataTrigger> 
          </Style.Triggers> 
         </Style> 
        </ListBox.ItemContainerStyle> 
        <i:Interaction.Triggers> 
         <i:EventTrigger EventName="MouseLeftButtonDown"> 
          <i:InvokeCommandAction Command="{Binding SetSelectedCommand}"/> 
         </i:EventTrigger> 
        </i:Interaction.Triggers> 
       </ListBox> 
      </Grid> 

Frage 1)

Ich brauche einen Befehl an einem "Mouseleftbuttondown" -Ereignis zu binden, wenn ich auf einem ListBoxItem in einem Listenfeld klicken . Ich habe die ACB-Lösung ausprobiert, kann sie aber nicht zum Laufen bringen. Endlich habe ich den obigen Code ausprobiert und ich kann es nicht auslösen, wenn ich auf einen Gegenstand klicke, aber unterhalb der Gegenstände, im leeren Teil der Listbox (nicht auf einem Listboxitem), toggelt er wie er sollte. Ich denke, ich muss meine XAML-Datei neu anordnen, aber ich habe es seit zwei Tagen versucht, aber nichts scheint zu funktionieren.

Der Befehl wird „setSelectedCommand“ benannt und umgesetzt wird, wie diese

internal class SetSelectedFlowCommand : ICommand 
{ 
    private FlowsViewModel _flowsViewModel; 

    public SetSelectedFlowCommand(FlowsViewModel flowsViewModel) 
    { 
     _flowsViewModel = flowsViewModel; 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    public event EventHandler CanExecuteChanged 
    { 
      add { CommandManager.RequerySuggested += value; } 
      remove { CommandManager.RequerySuggested -= value; } 
    } 

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

    public void Execute(object parameter) 
    { 
     _flowsViewModel.SetSelectedFlow(); 
    } 
} 

Wie gesagt, wenn ich auf dem ListBoxItem klicken - nichts happends, aber wenn ich in der List-Box klicken - der Befehl wird ausgelöst (aber nichts ist „ausgewählt“)

Frage 2

Wie Sie in der xAML oben zu sehen, die ich versuche, die Hintergrundfarbe für eine ListBoxItem zu setzen, basierend auf dem Wert .CanDeliver in einem Objekt, das wird in einem Verzeichnis im ViewModel gespeichert. Die Variable Flow ist das Wörterbuch und SelectedFlow soll der ausgewählte Flow sein.

Dies ist ein Bestellsystem und CanDeliver ist eine Variable, die dem Bediener/Benutzer mitteilt, ob genug Produkte für den Kunden verfügbar sind. Wenn es genug gibt, sollte das Listboxitem grün sein, ansonsten bleibt es weiß/grau. Verstehen Sie meine Frage? Kann ich es so machen? Verweisen auf ein Objekt in einem Wörterbuch? (Es ist von einem INotifyPropertyChanged in den Objekten ausgelöst)

Hoffe ihr könnt mir helfen kann, weil ich nicht mehr Haare aus meinem Kopf ziehen jetzt ;-)

+0

Es sollte stattdessen Property = "ListBoxItem.Background" richtige Eigenschaft = "Hintergrund" sein? – Archana

+0

Sie können beide Wege schreiben, auch wenn "ListBoxItem.Background" redundant ist. – ZombieGoose

Antwort

0

Sie brauchen nicht einen Event-Handler zu verwenden, wenn alle Sie möchten, dass das selectedItem abgerufen wird.Ich habe ein funktionierendes Beispiel bauen für Sie zu zeigen, wie Bindung nur verwenden (MVVM) Ihre Anforderungen in Frage zu erreichen:

C# (Ansichtsmodell):

using System; 
using System.Collections.Generic; 
using System.Windows; 
using System.ComponentModel; 
using System.Collections.ObjectModel; 

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      MyViewModel mvm = new MyViewModel() 
      { 
       Flows = new ObservableCollection<Flow>() 
       { 
        new Flow() { Name = "Flow1" }, 
        new Flow() { Name = "Flow2" }, 
        new Flow() { Name = "Flow3" , Amount=1}, 
        new Flow() { Name = "Flow4" } 
       } 
      }; 
      this.DataContext = mvm; 
     } 
    } 

    public class MyViewModel : ObservableObject 
    { 
     private Flow _selectedflow; 
     public ObservableCollection<Flow> Flows 
     { 
      get; 
      set; 
     } 

     public Flow SelectedFlow 
     { 
      get { return _selectedflow; } 
      set 
      { 
       if (value != _selectedflow) 
       { 
        _selectedflow = value; 
        RaisePropertyChanged("SelectedFlow"); 
       } 
      } 
     } 
    } 

    public class Flow : ObservableObject 
    { 
     private string _name; 
     private int _amount; 
     public string Name 
     { 
      get { return _name; } 
      set 
      { 
       if (value != _name) 
       { 
        _name = value; 
        RaisePropertyChanged("Name"); 
       } 
      } 
     } 

     public bool CanDeliver 
     { 
      get 
      { 
       return Amount > 0; 
      } 
     } 

     public int Amount 
     { 
      get { return _amount; } 
      set 
      { 
       if (value != _amount) 
       { 
        _amount = value; 
        RaisePropertyChanged("Amount"); 
        RaisePropertyChanged("CanDeliver"); 
       } 
      } 
     } 
    } 

    public class ObservableObject : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) 
     { 
      var handler = this.PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, e); 
      } 
     } 

     protected void RaisePropertyChanged(String propertyName) 
     { 
      OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

XAML:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="300" Width="350"> 
    <Grid> 
     <StackPanel Orientation="Vertical"> 
     <ListBox SelectedItem="{Binding SelectedFlow}" ItemsSource="{Binding Flows}" DisplayMemberPath="Name"> 
      <ListBox.ItemContainerStyle> 
       <Style TargetType="{x:Type ListBoxItem}" > 
        <Style.Triggers> 
         <DataTrigger Binding="{Binding CanDeliver, UpdateSourceTrigger=PropertyChanged}" Value="true" > 
          <Setter Property="Background" Value="DarkGreen" /> 
          <Setter Property="FontWeight" Value="Bold"/> 
         </DataTrigger> 
        </Style.Triggers> 
       </Style> 
      </ListBox.ItemContainerStyle> 
     </ListBox> 
     <TextBlock Text="{Binding SelectedFlow.Name}"/> 
     </StackPanel> 
    </Grid> 
</Window> 

Ergebnis: Sie können die Flow Artikel mit CanDeliver = True (Amount>0) hat einen grünen Hintergrund. Und die TextBlock zeigt die SelectedFlow.

enter image description here

+0

Oh, das funktionierte perfekt wie beabsichtigt! Ich danke dir sehr. Wenn ich genug Reputation hätte, würde ich deine Antwort auffrischen. :-) – ZombieGoose

+0

Keine Sorge @ZombieGoose, versuche nur, dir ein paar Haare zu sparen :) – Bolu