重新设计托管在 WinForm 应用程序中的 WPF 控件

Restyle WPF Control hosted in a WinForm app

我正在尝试为我的爱好应用程序添加深色主题支持。应用程序是 WinForms,我不想在 WPF 中重写 UI。因此,我尝试将几个 WPF 控件添加到我的应用程序中,主要是因为它们允许滚动条的主题化。

我正在按照本教程进行主机控制:https://www.codeproject.com/Articles/739902/How-to-Easily-Host-WPF-Control-inside-Windows-Form

到目前为止一切正常,除了我无法动态更改托管在 WinForms 中的 WPF 控件的背景颜色。我尝试了很多东西,提升 属性 改变,调用 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

实际上您的代码运行正常。您的 ListViewControl 具有误导性,因为它是一个包含 ListView 控件的 UserControl。您正确地将样式应用于 UserControl,但 ListView 遮盖了它,因此您看不到更改。如果你想要证明,你可以使包含的 ListViewBackground 透明。

要修复它,您可以更改 ListViewControl 中的 XAML,以便 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 控件匹配才能正常工作。