2017-05-31 4 views
1

Wie kann ich die SelectedItem von einem ListBox hervorgehoben werden nach der Einstellung der SelectedItem im ViewModel?Change SelectedItem von ListBox von ViewModel

Die ItemsSource gebunden ist an einen ObservableCollection von Bar (die Sammlung ist ein Mitglied einer Klasse Foo. Ein Knopf auf einen Befehl gebunden ist, die eine neue leere Bar Instanz zu der Sammlung hinzugefügt und anschließend setzt auch SelectedItem auf die neuen leeren Instanz.

die Instanz zur Sammlung nach Zugabe wird die ListBox die neue leeren Bar aktualisiert, um anzuzeigen. doch nach der SelectedItem Eigenschaft in der Ansichtsmodell Einstellung wird die neue Instanz nicht in den ListBox hervorgehoben, aber es festgelegt wird und das PropertyChanged Ereignis wird ausgelöst (SelectedItem wird an anderer Stelle in der Ansicht angezeigt).

Weitere Details:

INotifyPropertyChanged in einer Basisklasse Ansichtsmodell implementiert ist, und auch in den Foo und Bar Klassen implementiert.

The ListBox enthält eine benutzerdefinierte ItemTemplateBar Mitglieder anzuzeigen, und eine benutzerdefinierte ItemContainerStyle, die die für die BackgroundIsMouseOver Trigger modifiziert.

vereinfacht XAML:

<ListBox ItemsSource="{Binding Path=MyFoo.BarCollection}" 
     SelectedItem="{Binding Path=SelectedItem, 
         UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/> 

<Button Content="Add New Bar" 
     Command="{Binding Path=AddBarCommand}"/> 

vereinfacht Viewmodel:

private Foo _myFoo; 
public Foo MyFoo 
{ 
    get { return _myFoo; } 
    set { _myFoo= value; OnPropertyChanged("MyFoo"); } 
} 

private Bar _selectedItem; 
public Bar SelectedItem 
{ 
    get { return _selectedItem; } 
    set { _selectedItem = value; OnPropertyChanged("SelectedItem"); } 
} 

private void AddBar() 
{ 
    Bar newBar = new Bar(); 

    MyFoo.BarCollection.Add(newBar); 
    SelectedItem = newBar ; 
    _unsavedChanges = true; 
} 
+0

Was die Art der 'BarCollection' ist? –

+0

@Ed 'BarCollection' ist eine' ObservableCollection ' – jonmicjam

+0

Ich dachte, es musste sein. Mit dieser Annahme hat Ihr Code für mich funktioniert. Ist es möglich, dass der neue Gegenstand in einer wirklich blassgrauen Farbe hervorgehoben wird, die kaum von dem Fenster um ihn herum zu unterscheiden ist? Die standardmäßige nicht fokussierte Hervorhebungshintergrundfarbe in modernen Versionen von Fenstern kann perverserweise schwer zu bemerken sein. Wenn das der Fall ist, ist es leicht zu reparieren. –

Antwort

0

Ihr Code perfekt für mich gearbeitet.

enter image description here

Beachten Sie, dass „Bar 3“ ist ausgewählt, aber wenn die Listbox nicht Fokus hat, das Standard-Theme auf Windows 7 funktioniert ziemlich schwer zu halten Sie von zu bemerken. Und Windows 7 ist nicht einmal das Schlimmste. Unsere Anwendung verwendet WhiteSmoke als Standardhintergrund, und wir hatten große Probleme mit älteren Benutzern kann nicht feststellen, ob Listbox-Elemente ausgewählt sind oder nicht.

Glücklicherweise ist es eine triviale Lösung. Diese Ressourcen könnten genauso einfach in Window.Resources, in einer globalen ListBox Art oder in App.xaml sein. Es liegt an Ihnen, wie weit Sie sie anwenden möchten.

<ListBox 
    ItemsSource="{Binding MyFoo.BarCollection}" 
    SelectedItem="{Binding SelectedItem}" 
    > 
    <ListBox.Resources> 
     <SolidColorBrush 
      x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" 
      Color="{x:Static SystemColors.HighlightColor}" 
      Opacity="0.5" 
      /> 
     <SolidColorBrush 
      x:Key="{x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}" 
      Color="{x:Static SystemColors.HighlightTextColor}" 
      /> 
    </ListBox.Resources> 
</ListBox> 

"ältere" alt genug Sinn zu stimmen.


Und wenn Ihre Version von .NET die Existenz von SystemColors.InactiveSelectionHighlightTextBrushKey früher, ist dies wahrscheinlich eine Verfeinerung benutzen könnte, aber es funktioniert:

<ListBox 
    > 
    <ListBox.ItemContainerStyle> 
     <Style 
      TargetType="ListBoxItem" 
      BasedOn="{StaticResource {x:Type ListBoxItem}}" 
      > 
      <Style.Setters> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="ListBoxItem"> 
          <Grid 
           Background="{TemplateBinding Background}" 
           > 
           <ContentPresenter /> 
          </Grid> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style.Setters> 
      <Style.Triggers> 
       <Trigger Property="IsSelected" Value="True"> 
        <Setter 
         Property="Background" 
         Value="{StaticResource {x:Static SystemColors.HighlightBrushKey}}" 
         /> 
        <Setter 
         Property="Foreground" 
         Value="{StaticResource {x:Static SystemColors.HighlightTextBrushKey}}" 
         /> 
       </Trigger> 
       <MultiTrigger> 
        <MultiTrigger.Conditions> 
         <Condition Property="IsSelected" Value="True" /> 
         <Condition Property="IsEnabled" Value="False" /> 
        </MultiTrigger.Conditions> 
        <Setter 
         Property="Background" 
         Value="{StaticResource {x:Static SystemColors.InactiveCaptionBrushKey}}" 
         /> 
       </MultiTrigger> 
      </Style.Triggers> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 
+0

Genau das Problem, auf das ich stieß. Danke für die Lösung! Als Antwort markiert. (Sorry nicht genug bekannt zu +1) – jonmicjam

+0

NP, froh zu helfen. –

+0

Das Überschreiben des 'InactiveSelectionHighlightBrushKey' hat den Zweck erfüllt, obwohl es den Designer in VS2010 unterbricht. [Microsoft Docs] (https://msdn.microsoft.com/en-us/library/system.windows.systemcolors.inactiveselectionhighlightbrushkey (v = vs.110) .aspx) auch sagen, die "Pinsel ist' IsFrozen "-Eigenschaft ist * * true **, also kann es nicht geändert werden. " Ist das etwas, worüber man sich Sorgen machen muss? – jonmicjam

Verwandte Themen