Restyle WPF Control, размещенный в приложении WinForm

Я пытаюсь добавить поддержку Dark Theme в мое хобби-приложение. Приложение WinForms, и я не хочу переписывать пользовательский интерфейс в WPF. Поэтому вместо этого я пытаюсь добавить пару элементов управления WPF в свое приложение, главным образом потому, что они позволяют использовать полосу прокрутки.

Я следую этому руководству для управления хостом: https://www.codeproject.com/Articles/739902/How-to-Easily-Host-WPF-Control-inside-Windows-Form

Пока все работает, за исключением того, что я не могу динамически изменять цвет фона для своего элемента управления WPF, размещенного в WinForms. Я перепробовал много вещей, поднял измененное свойство, вызвал SetValue и т. Д., Но единственный способ, которым я мог управлять Background/Foreground - это напрямую установить их в XAML, а это не то, чего я хочу, потому что я хочу иметь возможность изменять цвет по желанию.

Вот что я представляю ближе всего к тому, что я хочу:

System.Windows.Style style = new System.Windows.Style();
  style.TargetType = typeof(WpfControls.ListViewControl);
  style.Setters.Add(new System.Windows.Setter(WpfControls.ListViewControl.BackgroundProperty, System.Windows.Media.Brushes.Pink));
style.Setters.Add(new System.Windows.Setter(WpfControls.ListViewControl.ForegroundProperty, System.Windows.Media.Brushes.Red));
this.listViewControl.Style = style;

Цвет не меняется. Код здесь: https://github.com/TheIronWolfModding/WpfControlsWinFormsHost/blob/master/WindowsFormsHost_Test/Form1.cs

1 ответ

Решение

На самом деле ваш код работает правильно. Ваш ListViewControl вводит в заблуждение, потому что это UserControl который содержит ListView контроль. Вы правильно применяете стиль к UserControl но ListView скрывает это, поэтому вы не можете видеть изменения. Вы можете сделать содержимое ListView"s Background Прозрачный, если вы хотите доказательства.

Чтобы исправить это, вы можете изменить свой XAML в ListViewControl таким образом ListView получает свой передний план и фон из родительского контейнера.

<ListView x:Name="listView" ItemsSource="{Binding ListEntries}" ScrollViewer.VerticalScrollBarVisibility="Visible"
          Background="{Binding Parent.Background, RelativeSource={RelativeSource Self}}"
          Foreground="{Binding Parent.Foreground, RelativeSource={RelativeSource Self}}">
</ListView>

... или... поскольку ваше намерение может состоять в том, чтобы изменить и многие другие свойства в стиле, и поэтому вам не нужно добавлять одинаковые привязки для каждого из них, вместо этого вы можете получить ссылку на содержимое ListView контролировать и устанавливать его стиль напрямую. Вместо этого оставьте XAML в покое и добавьте его в свой Form1.cs код:

System.Windows.Style style = new System.Windows.Style();
  style.TargetType = typeof(System.Windows.Controls.ListView);
  style.Setters.Add(new System.Windows.Setter(WpfControls.ListViewControl.BackgroundProperty, System.Windows.Media.Brushes.Pink));
style.Setters.Add(new System.Windows.Setter(WpfControls.ListViewControl.ForegroundProperty, System.Windows.Media.Brushes.Red));

//this.listViewControl.Style = style;
var listview = listViewControl.FindName ("listView") as System.Windows.Controls.ListView;
if (listview != null) {
    listview.Style = style;
}

примечание: обязательно измените TargetType, это должно соответствовать ListView контроль, чтобы это работало.

Другие вопросы по тегам