From f055c4c74226ec06a4a3ed75f76232ebb357051c Mon Sep 17 00:00:00 2001 From: koal44 Date: Tue, 27 Feb 2024 15:38:50 -0800 Subject: [PATCH 01/16] Fix ListView to be compatible when ListView.View is a GridView --- .../ViewModels/Windows/MainWindowViewModel.cs | 2 +- .../Views/Pages/Collections/ListViewPage.xaml | 49 +++- .../AutoSuggestBox/AutoSuggestBox.xaml | 4 +- src/Wpf.Ui/Controls/ListView/ListView.cs | 60 +++++ src/Wpf.Ui/Controls/ListView/ListView.xaml | 217 ++++++++++++++---- .../Controls/ListView/ListViewItem.xaml | 142 ++++++++---- 6 files changed, 367 insertions(+), 107 deletions(-) create mode 100644 src/Wpf.Ui/Controls/ListView/ListView.cs diff --git a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs index 7e96e95c5..43531e71d 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs @@ -72,7 +72,7 @@ public partial class MainWindowViewModel : ObservableObject { new NavigationViewItem(nameof(System.Windows.Controls.DataGrid), typeof(DataGridPage)), new NavigationViewItem(nameof(ListBox), typeof(ListBoxPage)), - new NavigationViewItem(nameof(ListView), typeof(ListViewPage)), + new NavigationViewItem(nameof(Ui.Controls.ListView), typeof(ListViewPage)), new NavigationViewItem(nameof(TreeView), typeof(TreeViewPage)), #if DEBUG new NavigationViewItem("TreeList", typeof(TreeListPage)), diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Collections/ListViewPage.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Collections/ListViewPage.xaml index 345d4b568..7ce461c3d 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Collections/ListViewPage.xaml +++ b/src/Wpf.Ui.Gallery/Views/Pages/Collections/ListViewPage.xaml @@ -12,7 +12,7 @@ Title="ListViewPage" d:DataContext="{d:DesignInstance local:ListViewPage, IsDesignTimeCreatable=False}" - d:DesignHeight="450" + d:DesignHeight="750" d:DesignWidth="800" ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}" ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}" @@ -30,8 +30,9 @@ \t</ListView.ItemTemplate>\n </ListView> - @@ -40,7 +41,7 @@ - + @@ -58,9 +59,10 @@ - @@ -99,7 +101,7 @@ - + + + + + <ListView ItemsSource="{Binding ViewModel.BasicListViewItems}">\n + \t<ListView.View>\n + \t\t<GridView>\n + \t\t\t<GridViewColumn DisplayMemberBinding="{Binding FirstName}" Header="First Name"/>\n + \t\t\t<GridViewColumn DisplayMemberBinding="{Binding LastName}" Header="Last Name"/>\n + \t\t\t<GridViewColumn DisplayMemberBinding="{Binding Company}" Header="Company"/>\n + \t\t</GridView>\n + \t</ListView.View>\n + </ListView> + + + + + + + + + + + diff --git a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml index d6c8aa11a..ec3330535 100644 --- a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml +++ b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml @@ -144,7 +144,7 @@ BorderThickness="1" CornerRadius="8" SnapsToDevicePixels="True"> - - + diff --git a/src/Wpf.Ui/Controls/ListView/ListView.cs b/src/Wpf.Ui/Controls/ListView/ListView.cs new file mode 100644 index 000000000..5c7c422f6 --- /dev/null +++ b/src/Wpf.Ui/Controls/ListView/ListView.cs @@ -0,0 +1,60 @@ +namespace Wpf.Ui.Controls; + +public class ListView : System.Windows.Controls.ListView +{ + public string ViewState + { + get => (string)GetValue(ViewStateProperty); + set => SetValue(ViewStateProperty, value); + } + + /// Identifies the dependency property. + public static readonly DependencyProperty ViewStateProperty = DependencyProperty.Register(nameof(ViewState), typeof(string), typeof(ListView), new FrameworkPropertyMetadata("Default", OnViewStateChanged)); + + private static void OnViewStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not ListView self) + { + return; + } + + self.OnViewStateChanged(e); + } + + protected virtual void OnViewStateChanged(DependencyPropertyChangedEventArgs e) + { + // derived classes can hook `ViewState` property changes by overriding this method + } + + public ListView() + { + Loaded += OnLoaded; + } + + private void OnLoaded(object sender, RoutedEventArgs e) + { + // immediately unsubscribe to prevent memory leaks + Loaded -= OnLoaded; + + // get the descriptor for the `View` property since the framework doesn't provide a public hook for it + var descriptor = DependencyPropertyDescriptor.FromProperty(System.Windows.Controls.ListView.ViewProperty, typeof(System.Windows.Controls.ListView)); + descriptor?.AddValueChanged(this, OnViewPropertyChanged); + UpdateViewState(); // set the initial state + } + + private void OnViewPropertyChanged(object? sender, EventArgs e) + { + UpdateViewState(); + } + + private void UpdateViewState() + { + var viewState = View is null ? "Default" : "GridView"; + SetCurrentValue(ViewStateProperty, viewState); + } + + static ListView() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(typeof(ListView))); + } +} diff --git a/src/Wpf.Ui/Controls/ListView/ListView.xaml b/src/Wpf.Ui/Controls/ListView/ListView.xaml index bef8c8cb2..90c506ac9 100644 --- a/src/Wpf.Ui/Controls/ListView/ListView.xaml +++ b/src/Wpf.Ui/Controls/ListView/ListView.xaml @@ -10,63 +10,178 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:Wpf.Ui.Controls"> - - + + - - + - - - + + \ No newline at end of file diff --git a/src/Wpf.Ui/Resources/Wpf.Ui.xaml b/src/Wpf.Ui/Resources/Wpf.Ui.xaml index d46cbda1e..27b33731a 100644 --- a/src/Wpf.Ui/Resources/Wpf.Ui.xaml +++ b/src/Wpf.Ui/Resources/Wpf.Ui.xaml @@ -14,6 +14,7 @@ + From 93dc778a7eacd776fd7613913cc092bb5fe5bb98 Mon Sep 17 00:00:00 2001 From: Mijail Todorovich Date: Fri, 15 Mar 2024 11:43:17 -0300 Subject: [PATCH 07/16] Avoid overflow in text input components Closes #973, closes #497 Use PassiveScrollViewer as PART_ContentHost instead of Decorator, just like TextBox --- src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml | 13 ++++++++---- src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml | 10 +++++++--- .../Controls/PasswordBox/PasswordBox.xaml | 20 +++++++++++++------ 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml b/src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml index 2e8e596c6..83c7c9125 100644 --- a/src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml +++ b/src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml @@ -44,12 +44,17 @@ - + HorizontalAlignment="Stretch" + Margin="{TemplateBinding Padding}" + CanContentScroll="False" + HorizontalScrollBarVisibility="Hidden" + IsDeferredScrollingEnabled="False" + Style="{DynamicResource DefaultTextBoxScrollViewerStyle}" + TextElement.Foreground="{TemplateBinding Foreground}" + VerticalScrollBarVisibility="Hidden" /> diff --git a/src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml b/src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml index b9788ab89..c5abd839a 100644 --- a/src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml +++ b/src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml @@ -85,11 +85,15 @@ IsTabStop="False" Foreground="{TemplateBinding Foreground}" /> - + CanContentScroll="False" + HorizontalScrollBarVisibility="Hidden" + IsDeferredScrollingEnabled="False" + Style="{DynamicResource DefaultTextBoxScrollViewerStyle}" + TextElement.Foreground="{TemplateBinding Foreground}" + VerticalScrollBarVisibility="Hidden" /> - + CanContentScroll="False" + HorizontalScrollBarVisibility="Hidden" + IsDeferredScrollingEnabled="False" + Style="{DynamicResource DefaultTextBoxScrollViewerStyle}" + TextElement.Foreground="{TemplateBinding Foreground}" + VerticalScrollBarVisibility="Hidden" /> @@ -174,11 +178,15 @@ TextElement.Foreground="{TemplateBinding Foreground}" /> - + CanContentScroll="False" + HorizontalScrollBarVisibility="Hidden" + IsDeferredScrollingEnabled="False" + Style="{DynamicResource DefaultTextBoxScrollViewerStyle}" + TextElement.Foreground="{TemplateBinding Foreground}" + VerticalScrollBarVisibility="Hidden" /> Date: Fri, 15 Mar 2024 11:55:05 -0300 Subject: [PATCH 08/16] Simplify PassiveScrollViewer usage by adding properties to style --- src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml | 6 +----- src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml | 7 +------ src/Wpf.Ui/Controls/PasswordBox/PasswordBox.xaml | 14 ++------------ src/Wpf.Ui/Controls/TextBox/TextBox.xaml | 3 --- .../Resources/DefaultTextBoxScrollViewerStyle.xaml | 5 +++++ 5 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml b/src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml index 83c7c9125..c33cebc9b 100644 --- a/src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml +++ b/src/Wpf.Ui/Controls/ComboBox/ComboBox.xaml @@ -49,12 +49,8 @@ VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="{TemplateBinding Padding}" - CanContentScroll="False" - HorizontalScrollBarVisibility="Hidden" - IsDeferredScrollingEnabled="False" Style="{DynamicResource DefaultTextBoxScrollViewerStyle}" - TextElement.Foreground="{TemplateBinding Foreground}" - VerticalScrollBarVisibility="Hidden" /> + TextElement.Foreground="{TemplateBinding Foreground}" /> diff --git a/src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml b/src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml index c5abd839a..361a9bb5b 100644 --- a/src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml +++ b/src/Wpf.Ui/Controls/NumberBox/NumberBox.xaml @@ -87,13 +87,8 @@ + TextElement.Foreground="{TemplateBinding Foreground}" /> + TextElement.Foreground="{TemplateBinding Foreground}" /> @@ -180,13 +175,8 @@ + TextElement.Foreground="{TemplateBinding Foreground}" /> + + + + + From d1fa429868d24b3894d4c72d2f93e740520128cc Mon Sep 17 00:00:00 2001 From: seasonyuu Date: Mon, 18 Mar 2024 15:58:18 +0800 Subject: [PATCH 09/16] Fix TitleBarButton Foreground error when change theme --- src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml | 2 +- .../Controls/TitleBar/TitleBarButton.cs | 54 +++++++++++++++++-- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml b/src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml index 110a281b8..f033043fd 100644 --- a/src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml +++ b/src/Wpf.Ui/Controls/TitleBar/TitleBar.xaml @@ -41,7 +41,7 @@ Width="72" Height="72" Focusable="False"> - + diff --git a/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs b/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs index 33d2deb9e..04d93633e 100644 --- a/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs +++ b/src/Wpf.Ui/Controls/TitleBar/TitleBarButton.cs @@ -43,6 +43,18 @@ public class TitleBarButton : Wpf.Ui.Controls.Button nameof(MouseOverButtonsForeground), typeof(Brush), typeof(TitleBarButton), + new FrameworkPropertyMetadata( + null, + FrameworkPropertyMetadataOptions.Inherits + ) + ); + /// + /// Property for . + /// + public static readonly DependencyProperty RenderButtonsForegroundProperty = DependencyProperty.Register( + nameof(RenderButtonsForeground), + typeof(Brush), + typeof(TitleBarButton), new FrameworkPropertyMetadata( SystemColors.ControlTextBrush, FrameworkPropertyMetadataOptions.Inherits @@ -66,23 +78,52 @@ public Brush ButtonsForeground get => (Brush)GetValue(ButtonsForegroundProperty); set => SetValue(ButtonsForegroundProperty, value); } + /// /// Foreground of the navigation buttons while mouse over. /// - public Brush MouseOverButtonsForeground + public Brush? MouseOverButtonsForeground { get => (Brush)GetValue(MouseOverButtonsForegroundProperty); set => SetValue(MouseOverButtonsForegroundProperty, value); } + public Brush RenderButtonsForeground + { + get => (Brush)GetValue(RenderButtonsForegroundProperty); + set => SetValue(RenderButtonsForegroundProperty, value); + } + public bool IsHovered { get; private set; } private User32.WM_NCHITTEST _returnValue; private Brush _defaultBackgroundBrush = Brushes.Transparent; //Should it be transparent? - private Brush _cacheButtonsForeground = SystemColors.ControlTextBrush; // cache ButtonsForeground while mouse over private bool _isClickedDown; + public TitleBarButton() + { + Loaded += TitleBarButton_Loaded; + Unloaded += TitleBarButton_Unloaded; + } + + private void TitleBarButton_Unloaded(object sender, RoutedEventArgs e) + { + DependencyPropertyDescriptor.FromProperty(ButtonsForegroundProperty, typeof(Brush)) + .RemoveValueChanged(this, OnButtonsForegroundChanged); + } + + private void TitleBarButton_Loaded(object sender, RoutedEventArgs e) + { + DependencyPropertyDescriptor.FromProperty(ButtonsForegroundProperty, typeof(Brush)) + .AddValueChanged(this, OnButtonsForegroundChanged); + } + + private void OnButtonsForegroundChanged(object sender, EventArgs e) + { + SetCurrentValue(RenderButtonsForegroundProperty, IsHovered ? MouseOverButtonsForeground : ButtonsForeground); + } + /// /// Forces button background to change. /// @@ -92,8 +133,11 @@ public void Hover() return; Background = MouseOverBackground; - _cacheButtonsForeground = ButtonsForeground; - ButtonsForeground = MouseOverButtonsForeground; + if (MouseOverButtonsForeground != null) + { + RenderButtonsForeground = MouseOverButtonsForeground; + } + IsHovered = true; } @@ -106,7 +150,7 @@ public void RemoveHover() return; Background = _defaultBackgroundBrush; - ButtonsForeground = _cacheButtonsForeground; + RenderButtonsForeground = ButtonsForeground; IsHovered = false; _isClickedDown = false; From 612a785d79468bf97858a67d2bfca2c0091fab75 Mon Sep 17 00:00:00 2001 From: koal44 Date: Mon, 18 Mar 2024 13:21:21 -0700 Subject: [PATCH 10/16] Improve lineargradient border for TextBox in Light/Dark theme (also effects PasswordBox and NumberBox) --- src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml | 7 +++++-- src/Wpf.Ui/Controls/TextBox/TextBox.xaml | 6 +++--- src/Wpf.Ui/Resources/Theme/Dark.xaml | 9 +++------ src/Wpf.Ui/Resources/Theme/Light.xaml | 9 +++------ 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml index 0ff6b51ce..0a4774c7d 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml +++ b/src/Wpf.Ui.Gallery/Views/Pages/Text/TextBoxPage.xaml @@ -11,7 +11,7 @@ controls:PageControlDocumentation.DocumentationType="{x:Type ui:TextBox}" d:DataContext="{d:DesignInstance local:TextBoxPage, IsDesignTimeCreatable=False}" - d:DesignHeight="450" + d:DesignHeight="750" d:DesignWidth="800" ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}" ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}" @@ -34,7 +34,10 @@ Margin="0,36,0,0" HeaderText="A multi-line TextBox." XamlCode="<ui:TextBox PlaceholderText="Type something..."TextWrapping="Wrap" />"> - + diff --git a/src/Wpf.Ui/Controls/TextBox/TextBox.xaml b/src/Wpf.Ui/Controls/TextBox/TextBox.xaml index bbfc4cca1..3b620802b 100644 --- a/src/Wpf.Ui/Controls/TextBox/TextBox.xaml +++ b/src/Wpf.Ui/Controls/TextBox/TextBox.xaml @@ -14,7 +14,7 @@ xmlns:controls="clr-namespace:Wpf.Ui.Controls" xmlns:system="clr-namespace:System;assembly=System.Runtime"> - 1,1,1,0 + 1,1,1,1 0,0,0,1 10,0,0,0 0,0,10,0 @@ -206,8 +206,8 @@ BorderBrush="Transparent" Command="{Binding Path=TemplateButtonCommand, RelativeSource={RelativeSource TemplatedParent}}" Cursor="Arrow" - IsTabStop="False" - Foreground="{DynamicResource TextControlButtonForeground}"> + Foreground="{DynamicResource TextControlButtonForeground}" + IsTabStop="False"> diff --git a/src/Wpf.Ui/Resources/Theme/Dark.xaml b/src/Wpf.Ui/Resources/Theme/Dark.xaml index b2f609801..5a8200d85 100644 --- a/src/Wpf.Ui/Resources/Theme/Dark.xaml +++ b/src/Wpf.Ui/Resources/Theme/Dark.xaml @@ -267,13 +267,10 @@ - - - - + - - + + diff --git a/src/Wpf.Ui/Resources/Theme/Light.xaml b/src/Wpf.Ui/Resources/Theme/Light.xaml index cf93807bb..a8288560c 100644 --- a/src/Wpf.Ui/Resources/Theme/Light.xaml +++ b/src/Wpf.Ui/Resources/Theme/Light.xaml @@ -268,13 +268,10 @@ - - - - + - - + + From 9c2391a8d21abbbeb1a1922f2b1d7a1c8afc0bff Mon Sep 17 00:00:00 2001 From: koal44 Date: Tue, 19 Mar 2024 07:55:51 -0700 Subject: [PATCH 11/16] Re-implement custom ui:ListView class and remove the ListViewViewStateConverter --- .../ViewModels/Windows/MainWindowViewModel.cs | 2 +- .../Views/Pages/Collections/ListViewPage.xaml | 24 +++---- .../AutoSuggestBox/AutoSuggestBox.xaml | 8 +-- src/Wpf.Ui/Controls/ListView/ListView.cs | 65 +++++++++++++++++++ src/Wpf.Ui/Controls/ListView/ListView.xaml | 17 ++--- .../Controls/ListView/ListViewItem.xaml | 12 +--- .../ViewToListViewViewStateConverter.cs | 28 -------- 7 files changed, 92 insertions(+), 64 deletions(-) create mode 100644 src/Wpf.Ui/Controls/ListView/ListView.cs delete mode 100644 src/Wpf.Ui/Converters/ViewToListViewViewStateConverter.cs diff --git a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs index 7e96e95c5..43531e71d 100644 --- a/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs +++ b/src/Wpf.Ui.Gallery/ViewModels/Windows/MainWindowViewModel.cs @@ -72,7 +72,7 @@ public partial class MainWindowViewModel : ObservableObject { new NavigationViewItem(nameof(System.Windows.Controls.DataGrid), typeof(DataGridPage)), new NavigationViewItem(nameof(ListBox), typeof(ListBoxPage)), - new NavigationViewItem(nameof(ListView), typeof(ListViewPage)), + new NavigationViewItem(nameof(Ui.Controls.ListView), typeof(ListViewPage)), new NavigationViewItem(nameof(TreeView), typeof(TreeViewPage)), #if DEBUG new NavigationViewItem("TreeList", typeof(TreeListPage)), diff --git a/src/Wpf.Ui.Gallery/Views/Pages/Collections/ListViewPage.xaml b/src/Wpf.Ui.Gallery/Views/Pages/Collections/ListViewPage.xaml index a9a6f6e48..35cdf639c 100644 --- a/src/Wpf.Ui.Gallery/Views/Pages/Collections/ListViewPage.xaml +++ b/src/Wpf.Ui.Gallery/Views/Pages/Collections/ListViewPage.xaml @@ -30,18 +30,18 @@ \t</ListView.ItemTemplate>\n </ListView> - - + - - + + @@ -59,14 +59,14 @@ - - + @@ -100,8 +100,8 @@ Text="{Binding Company, Mode=OneWay}" /> - - + + - - + - - + + diff --git a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml index d6c8aa11a..389daa086 100644 --- a/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml +++ b/src/Wpf.Ui/Controls/AutoSuggestBox/AutoSuggestBox.xaml @@ -144,7 +144,7 @@ BorderThickness="1" CornerRadius="8" SnapsToDevicePixels="True"> - - + - - + + diff --git a/src/Wpf.Ui/Controls/ListView/ListView.cs b/src/Wpf.Ui/Controls/ListView/ListView.cs new file mode 100644 index 000000000..44efcd2a9 --- /dev/null +++ b/src/Wpf.Ui/Controls/ListView/ListView.cs @@ -0,0 +1,65 @@ +namespace Wpf.Ui.Controls; + +public class ListView : System.Windows.Controls.ListView +{ + public ListViewViewState ViewState + { + get => (ListViewViewState)GetValue(ViewStateProperty); + set => SetValue(ViewStateProperty, value); + } + + /// Identifies the dependency property. + public static readonly DependencyProperty ViewStateProperty = DependencyProperty.Register(nameof(ViewState), typeof(ListViewViewState), typeof(ListView), new FrameworkPropertyMetadata(ListViewViewState.Default, OnViewStateChanged)); + + private static void OnViewStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is not ListView self) + { + return; + } + + self.OnViewStateChanged(e); + } + + protected virtual void OnViewStateChanged(DependencyPropertyChangedEventArgs e) + { + // derived classes can hook `ViewState` property changes by overriding this method + } + + public ListView() + { + Loaded += OnLoaded; + } + + private void OnLoaded(object sender, RoutedEventArgs e) + { + // immediately unsubscribe to prevent memory leaks + Loaded -= OnLoaded; + + // get the descriptor for the `View` property since the framework doesn't provide a public hook for it + var descriptor = DependencyPropertyDescriptor.FromProperty(System.Windows.Controls.ListView.ViewProperty, typeof(System.Windows.Controls.ListView)); + descriptor?.AddValueChanged(this, OnViewPropertyChanged); + UpdateViewState(); // set the initial state + } + + private void OnViewPropertyChanged(object? sender, EventArgs e) + { + UpdateViewState(); + } + + private void UpdateViewState() + { + ListViewViewState viewState = View switch + { + System.Windows.Controls.GridView => ListViewViewState.GridView, + null => ListViewViewState.Default, + _ => ListViewViewState.Default + }; + SetCurrentValue(ViewStateProperty, viewState); + } + + static ListView() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ListView), new FrameworkPropertyMetadata(typeof(ListView))); + } +} diff --git a/src/Wpf.Ui/Controls/ListView/ListView.xaml b/src/Wpf.Ui/Controls/ListView/ListView.xaml index 3cc76c08d..1af21cff0 100644 --- a/src/Wpf.Ui/Controls/ListView/ListView.xaml +++ b/src/Wpf.Ui/Controls/ListView/ListView.xaml @@ -8,12 +8,9 @@ + xmlns:controls="clr-namespace:Wpf.Ui.Controls"> - - - + - + - -