Skip to content

Instantly share code, notes, and snippets.

@BYJRK
Last active March 6, 2023 08:38
Show Gist options
  • Save BYJRK/b01111d06b3c4ab96e876aa7c130e3aa to your computer and use it in GitHub Desktop.
Save BYJRK/b01111d06b3c4ab96e876aa7c130e3aa to your computer and use it in GitHub Desktop.
A simple WPF Window whose controls, styles, triggers, event, etc. are written in code-behind only
<Window ...>
<Window.Resources>
<local:BrightnessToBoolConverter x:Key="conv" />
<Style TargetType="Button">
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="Black" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<EventSetter Event="Click" Handler="OnButtonClicked" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Background, Converter={StaticResource conv}}" Value="False">
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
</Window>
using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
namespace BuiltInBrushesViewer;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
var panel = new VirtualizingStackPanel();
typeof(Brushes)
.GetProperties(BindingFlags.Public | BindingFlags.Static)
.ToList()
.ForEach(prop =>
{
var brush = (SolidColorBrush)prop.GetValue(null)!;
var btn = new Button
{
Background = brush,
Content = prop.Name,
Style = GetButtonStyle()
};
panel.Children.Add(btn);
});
this.Content = new ScrollViewer
{
HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled,
Content = panel
};
}
/// <summary>
/// 创建一个 <see cref="Button"/> 的样式
/// </summary>
public Style GetButtonStyle()
{
Style style = new Style(typeof(Button));
// FontSize 的 value 不能写 16,因为是整数,不符合 FontSize 属性的要求(这里不会自动转换类型)
style.Setters.Add(new Setter(Button.FontSizeProperty, 16.0));
style.Setters.Add(new Setter(Button.ForegroundProperty, Brushes.Black));
style.Setters.Add(new Setter(Button.FocusVisualStyleProperty, null));
// Handler 不能直接写 lambda 表达式,会报 ArgumentException,需要外面套一层 RoutedEventHandler
style.Setters.Add(new EventSetter(Button.ClickEvent, new RoutedEventHandler((object sender, RoutedEventArgs e) =>
{
if (sender is not Button btn) return;
Clipboard.SetText((string)btn.Content);
})));
// 添加一个 DataTrigger
DataTrigger foregroundTrigger = new DataTrigger
{
Binding = new Binding
{
Path = new PropertyPath("Background"),
RelativeSource = RelativeSource.Self,
Converter = new BrightnessToBoolConverter()
},
Value = false
};
foregroundTrigger.Setters.Add(new Setter(Button.ForegroundProperty, Brushes.White));
style.Triggers.Add(foregroundTrigger);
return style;
}
}
public class BrightnessToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not SolidColorBrush b)
throw new ArgumentException(nameof(value));
int color = (b.Color.R + b.Color.G + b.Color.B) / 3;
return color >= 127;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment