Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ComboBox / Popup crashes after Theme switching. Other controls work as expected. #15115

Open
timunie opened this issue Mar 25, 2024 · 2 comments
Labels

Comments

@timunie
Copy link
Contributor

timunie commented Mar 25, 2024

Here I've simplified this example even further, getting rid of absolutely everything superfluous. In this example, the themes are not applied at all. If I apply one of the themes, I lose AccentColor, and all other colors are not changed at all. If I replace

App.Current.Resources["SystemAccentColor"] = new SolidColorBrush(new Color(255, 137, 97, 204));

On

App.Current.Resources["SystemAccentColor"] = new Color(255, 137, 97, 97, 204);

Then I have SystemAccentColor replaced, but still this method does not work in any way on other colors, it is not applied in any way.

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:AvaloniaApplication1.ViewModels"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
        x:Class="AvaloniaApplication1.Views.MainWindow"
        x:DataType="vm:MainWindowViewModel"
        Icon="/Assets/avalonia-logo.ico"
        Title="AvaloniaApplication1">

    <Design.DataContext>
        <!-- This only sets the DataContext for the previewer in an IDE,
             to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
        <vm:MainWindowViewModel/>
    </Design.DataContext>

	<Grid Grid.Row="0" ColumnDefinitions="4*, 1*" RowDefinitions="1*, 5*">
		<ComboBox Grid.Column="0" Grid.Row="0"
		ItemsSource="{CompiledBinding Themes}"
		DisplayMemberBinding="{CompiledBinding Name, Mode=TwoWay}"
		HorizontalAlignment="Stretch"
		SelectedItem="{CompiledBinding CurrentTheme, Mode=TwoWay}" />
		<Button Grid.Column="1" Grid.Row="0" Content="Apply" Command="{CompiledBinding ChangeSettings}" />

		<TabControl TabStripPlacement="Top" Grid.Column="0" Grid.Row="1">
			<TabControl.ItemsPanel>
				<ItemsPanelTemplate>
					<UniformGrid Rows="1" />
				</ItemsPanelTemplate>
			</TabControl.ItemsPanel>
			<TabItem>
				<TabItem.Header>
					<TextBlock Text="1" TextAlignment="Center" />
				</TabItem.Header>
				<ContentControl Content="Text 1" />
			</TabItem>
			<TabItem>
				<TabItem.Header>
					<TextBlock Text="2" TextAlignment="Center" />
				</TabItem.Header>
				<ContentControl Content="Text 2" />
			</TabItem>
		</TabControl>

	</Grid>
	
</Window>

MainWindowViewModel.cs

using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.Threading;
using ReactiveUI;
using System;
using System.Collections.ObjectModel;

namespace AvaloniaApplication1.ViewModels
{
    public class MainWindowViewModel : ViewModelBase
    {
        private Theme _currentTheme;
        public Theme CurrentTheme
        {
            get => _currentTheme;
            set => this.RaiseAndSetIfChanged(ref _currentTheme, value);
        }

        private ObservableCollection<Theme> _themes;
        public ObservableCollection<Theme> Themes
        {
            get => _themes;
            set => this.RaiseAndSetIfChanged(ref _themes, value);
        }

        public MainWindowViewModel()
        {
            Themes = new ObservableCollection<Theme>()
            {
                new Theme() { Name = "1" },
                new Theme() { Name = "2" }
            };

            CurrentTheme = Themes[0];
        }

        public void ChangeSettings()
        {
            if (CurrentTheme.Name == "1")
            {
                App.Current.Resources["SystemAccentColor"] = new SolidColorBrush(new Color(255, 137, 97, 204));
                App.Current.Resources["SystemAltHighColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemAltLowColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemAltMediumColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemAltMediumHighColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemAltMediumLowColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemBaseHighColor"] = new SolidColorBrush(new Color(255, 255, 255, 255));
                App.Current.Resources["SystemBaseLowColor"] = new SolidColorBrush(new Color(255, 100, 87, 107));
                App.Current.Resources["SystemBaseMediumColor"] = new SolidColorBrush(new Color(255, 182, 170, 188));
                App.Current.Resources["SystemBaseMediumHighColor"] = new SolidColorBrush(new Color(255, 203, 191, 208));
                App.Current.Resources["SystemBaseMediumLowColor"] = new SolidColorBrush(new Color(255, 141, 129, 147));
                App.Current.Resources["SystemChromeAltLowColor"] = new SolidColorBrush(new Color(255, 203, 191, 208));
                App.Current.Resources["SystemChromeBlackHighColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemChromeBlackLowColor"] = new SolidColorBrush(new Color(255, 203, 191, 208));
                App.Current.Resources["SystemChromeBlackMediumLowColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemChromeBlackMediumColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemChromeDisabledHighColor"] = new SolidColorBrush(new Color(255, 100, 87, 107));
                App.Current.Resources["SystemChromeDisabledLowColor"] = new SolidColorBrush(new Color(255, 182, 170, 188));
                App.Current.Resources["SystemChromeGrayColor"] = new SolidColorBrush(new Color(255, 162, 149, 168));
                App.Current.Resources["SystemChromeHighColor"] = new SolidColorBrush(new Color(255, 162, 149, 168));
                App.Current.Resources["SystemChromeLowColor"] = new SolidColorBrush(new Color(255, 51, 32, 65));
                App.Current.Resources["SystemChromeMediumColor"] = new SolidColorBrush(new Color(255, 63, 46, 75));
                App.Current.Resources["SystemChromeMediumLowColor"] = new SolidColorBrush(new Color(255, 88, 73, 96));
                App.Current.Resources["SystemChromeWhiteColor"] = new SolidColorBrush(new Color(255, 255, 255, 255));
                App.Current.Resources["SystemErrorTextColor"] = new SolidColorBrush(new Color(255, 255, 240, 0));
                App.Current.Resources["SystemListLowColor"] = new SolidColorBrush(new Color(255, 63, 46, 7));
                App.Current.Resources["SystemListMediumColor"] = new SolidColorBrush(new Color(255, 100, 87, 107));
                App.Current.Resources["SystemRegionColor"] = new SolidColorBrush(new Color(255, 38, 39, 56));
            }
            else
            {
                App.Current.Resources["SystemAccentColor"] = new SolidColorBrush(new Color(255, 137, 97, 204));
                App.Current.Resources["SystemAltHighColor"] = new SolidColorBrush(new Color(255, 255, 255, 255));
                App.Current.Resources["SystemAltLowColor"] = new SolidColorBrush(new Color(255, 255, 255, 255));
                App.Current.Resources["SystemAltMediumColor"] = new SolidColorBrush(new Color(255, 255, 255, 255));
                App.Current.Resources["SystemAltMediumHighColor"] = new SolidColorBrush(new Color(255, 255, 255, 255));
                App.Current.Resources["SystemAltMediumLowColor"] = new SolidColorBrush(new Color(255, 255, 255, 255));
                App.Current.Resources["SystemBaseHighColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemBaseLowColor"] = new SolidColorBrush(new Color(255, 238, 206, 255));
                App.Current.Resources["SystemBaseMediumColor"] = new SolidColorBrush(new Color(255, 169, 135, 188));
                App.Current.Resources["SystemBaseMediumHighColor"] = new SolidColorBrush(new Color(255, 123, 88, 144));
                App.Current.Resources["SystemBaseMediumLowColor"] = new SolidColorBrush(new Color(255, 146, 112, 166));
                App.Current.Resources["SystemChromeAltLowColor"] = new SolidColorBrush(new Color(255, 123, 88, 144));
                App.Current.Resources["SystemChromeBlackHighColor"] = new SolidColorBrush(new Color(255, 0, 0, 0));
                App.Current.Resources["SystemChromeBlackLowColor"] = new SolidColorBrush(new Color(255, 238, 206, 255));
                App.Current.Resources["SystemChromeBlackMediumColor"] = new SolidColorBrush(new Color(255, 123, 88, 144));
                App.Current.Resources["SystemChromeBlackMediumLowColor"] = new SolidColorBrush(new Color(255, 169, 135, 188));
                App.Current.Resources["SystemChromeDisabledHighColor"] = new SolidColorBrush(new Color(255, 238, 206, 255));
                App.Current.Resources["SystemChromeDisabledLowColor"] = new SolidColorBrush(new Color(255, 169, 135, 188));
                App.Current.Resources["SystemChromeGrayColor"] = new SolidColorBrush(new Color(255, 146, 112, 166));
                App.Current.Resources["SystemChromeHighColor"] = new SolidColorBrush(new Color(255, 238, 206, 255));
                App.Current.Resources["SystemChromeLowColor"] = new SolidColorBrush(new Color(255, 254, 234, 255));
                App.Current.Resources["SystemChromeMediumColor"] = new SolidColorBrush(new Color(255, 251, 228, 255));
                App.Current.Resources["SystemChromeMediumLowColor"] = new SolidColorBrush(new Color(255, 254, 234, 255));
                App.Current.Resources["SystemChromeWhiteColor"] = new SolidColorBrush(new Color(255, 255, 255, 255));
                App.Current.Resources["SystemErrorTextColor"] = new SolidColorBrush(new Color(255, 197, 5, 0));
                App.Current.Resources["SystemListLowColor"] = new SolidColorBrush(new Color(255, 251, 228, 255));
                App.Current.Resources["SystemListMediumColor"] = new SolidColorBrush(new Color(255, 238, 206, 255));
                App.Current.Resources["SystemRegionColor"] = new SolidColorBrush(new Color(255, 254, 246, 255));
            }
        }
    }


    public class Theme
    {
        public string Name { get; set; }
    }
}

What else do I have to send you to show you that this code doesn't work????
Only SystemAccentColor is changed and that's it, other colors are not affected.

unknown_2024.03.22-14.55.mp4

Originally posted by @H4CK3R0FF1C14L in #15072 (reply in thread)

@H4CK3R0FF1C14L
Copy link

I tried to override all the brushes that are found here through this method, but it doesn't work quite as it should, because many colors are not changed. For example, the color of the text, which makes changing the theme look very strange.

The original method looks much simpler and changes the theme as it should, except that the ComboBox crashes the whole application for some reason.

In this post was attached an example with disabled virtualization of ComboBox and some array. But as far as I know, in the latest version virtualization was removed from ComboBox.

@maxkatz6 maxkatz6 added the bug label Jun 27, 2024
@SimonORorke
Copy link

SimonORorke commented Jun 29, 2024

In this post was attached an example with disabled virtualization of ComboBox and some array. But as far as I know, in the latest version virtualization was removed from ComboBox.

Yes I saw that, and I can confirm that ComboBox no longer has the VirtualizationMode property the author provided in his solution example. Furthermore, I could not translate that solution example to MVVM.

My interim workaround (which could become the permanent workaround) is to use a ListBox instead of a ComboBox.

However, it would be nice, though not essential, to be able to use a ComboBox. So I would be interested to hear any suggestions for a workaround. Here's a cutdown version of my view. Hopefully that will be enough context to show what I need. First, here's the XAML:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vm="using:FalconProgrammer.ViewModel"
        x:Class="FalconProgrammer.Views.ColourSchemeWindow"
        x:DataType="vm:ColourSchemeWindowViewModel">
    <ComboBox
        ItemsSource="{Binding ColourSchemes}"
        SelectedItem="{Binding ColourScheme}" />
</Window>

And here's the code behind:

public partial class ColourSchemeWindow : Window {
    public ColourSchemeWindow() {
        InitializeComponent();
    }

    protected override void OnLoaded(RoutedEventArgs e) {
        var viewModel = (ColourSchemeWindowViewModel)DataContext!;
        viewModel.ChangeColourScheme += ViewModelOnChangeColourScheme;
    }

    private static void ViewModelOnChangeColourScheme(object? sender, ColourSchemeId e) {
        // This is just a static method that changes the theme's colour scheme to the one indicated by 
        // the method's enum parameter.
        ColourScheme.Select(e);
    }
}

To clarify, the application crash happens for me if, having already used the ComboBox once to change the theme, I then attempt to open the ComboBox's drop-down list (Popup), either with the mouse or with the F4 keyboard shortcut.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants