Benutzer mit den meisten Antworten
How can Properties on UserControls other then TextBoxes being changed on a visual state change of a listViewItem

Frage
-
In Windows 8.1 it is extremly difficult to implement color inversions on listview items, if the item content is not a simple text box.
For that you have to implement the full item container style referenced here (NOT the ListViewItemPresenter version):
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj709921.aspx
Additionaly you must implement and replace the default contentPresenter in the container style template with a custom one.
Doing this we are able to track all visual states with debug printouts and with the visualtreehelper fired for each list item.
Here we recognized missing visual states not beeing fired. E.g. the Selected state never appeared and other states only come up unreliably. So with this precondition it was nearly impossibly to implement a working style as shown above where the folder icon is a path with a Fill property to exchange on visual state changes.
On Windows 10 it seems to be even worse. Almost none of the visual states are fired only PointerOver and Normal. So we are not able to change the foreground brush meaning Fill property of paths anymore.
For a workaround we thought about using property changed events on the Foreground dependency properties of textboxes located in the listview item content. But these are never fired. The color exchange during visual state changes seems to be done on a lower layer (GPU thread maybe) where we have no access to.
So now my question:
How can Properties on UserControls other then TextBoxes being changed on a visual state change of a listViewItem ?
Hope you have some suggestions. Maybe we are not seeing the ovious easiest way to accomplish this.
Antworten
-
Ok, got the answer myself.
Just inherite from ListViewItemPresenter and implement everyhing you need in there. Something like that:
public class AppointmentListViewItemPresenter : ListViewItemPresenter { private ListView _parentListView; private PushPinControl _pushPin; private Brush _previousBackgroundBrush; public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register( "IsSelected", typeof (bool), typeof (AppointmentListViewItemPresenter), new PropertyMetadata(default(bool), PropertyChangedCallback)); private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs args) { var presenter = d as AppointmentListViewItemPresenter; if (presenter == null) return; presenter.SetSelectionState(); } private void SetSelectionState() { if (IsSelected) { _previousBackgroundBrush = _pushPin.Background; _pushPin.Background = Application.Current.Resources["PushPinSelectedBackgroundBrush"] as SolidColorBrush; } else { _pushPin.Background = _previousBackgroundBrush; } } public bool IsSelected { get { return (bool) GetValue(IsSelectedProperty); } set { SetValue(IsSelectedProperty, value); } } public AppointmentListViewItemPresenter() { Loaded += AppointmentListViewItemPresenter_Loaded; Unloaded += AppointmentListViewItemPresenter_Unloaded; } private void AppointmentListViewItemPresenter_Unloaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) { Loaded -= AppointmentListViewItemPresenter_Loaded; Unloaded -= AppointmentListViewItemPresenter_Unloaded; Tapped -= AppointmentListViewItemPresenter_Tapped; } private void AppointmentListViewItemPresenter_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e) { Tapped += AppointmentListViewItemPresenter_Tapped; _parentListView = this.GetFirstAncestorOfType<ListView>(); _pushPin = this.GetFirstDescendantOfType<PushPinControl>(); if (_pushPin == null) return; } private void AppointmentListViewItemPresenter_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e) { if (_parentListView == null) return; var lastSelectedItem = _parentListView.GetDescendantsOfType<AppointmentListViewItemPresenter>().FirstOrDefault(p => p.IsSelected); if (_parentListView.SelectedItem == DataContext) { //handle item selection Debug.WriteLine("AppointmentListViewItemPresenter.cs | AppointmentListViewItemPresenter_Tapped | Selected index {0}", _parentListView.SelectedIndex); IsSelected = true; } if (lastSelectedItem != null) { lastSelectedItem.IsSelected = false; } }
- Als Antwort vorgeschlagen Tom Lambert (Koopakiller) Dienstag, 25. August 2015 13:25
- Als Antwort markiert Dimitar DenkovMicrosoft contingent staff, Moderator Mittwoch, 2. September 2015 09:28