WPF 中是否有颜色对话框?

15

我正在寻找一个适用于WPF的颜色对话框,是否有内置的? 应该自己编写还是使用Win 32交互? 如果选择后者,如何实现?


13
真的...WPF...居然没有颜色选择器...这是怎么回事... - serhio
2
请查看Extended WPF Toolkit,这是一组WPF控件。 - jwillmer
1
Extended WPF Toolkit中有一个ColorPicker Control,可以放置在对话框上。 - SpeedCoder5
@serhio,你可以在WPF中使用颜色选择器而无需第三方库,请看我的回答。 - MAXE
4个回答

5

看起来非常不错。如果我只能显示颜色轮而不是所有其他控件,我会使用它。 - Steven

4
这是一个使用附加属性的简单颜色选择器,如果有人正在寻找示例代码,可以参考一下。
public static class BrushExtender
{
    public readonly static DependencyProperty BrushProperty = DependencyProperty.RegisterAttached("Brush", typeof(Brush), typeof(BrushExtender), new PropertyMetadata(Brushes.Black,DoBrushChanged));

    public readonly static DependencyProperty RedChannelProperty = DependencyProperty.RegisterAttached("RedChannel", typeof(int), typeof(BrushExtender), new PropertyMetadata(DoColorChangedRed));

    public readonly static DependencyProperty GreenChannelProperty = DependencyProperty.RegisterAttached("GreenChannel", typeof(int), typeof(BrushExtender), new PropertyMetadata(DoColorChangedGreen));

    public readonly static DependencyProperty BlueChannelProperty = DependencyProperty.RegisterAttached("BlueChannel", typeof(int), typeof(BrushExtender), new PropertyMetadata(DoColorChangedBlue));

    public readonly static DependencyProperty AlphaChannelProperty = DependencyProperty.RegisterAttached("AlphaChannel", typeof(int), typeof(BrushExtender), new PropertyMetadata(DoColorChangedAlpha));

    public readonly static DependencyProperty ColourValueProperty = DependencyProperty.RegisterAttached("ColourValue", typeof(string), typeof(BrushExtender), new PropertyMetadata(DoValueChanged));

    public static void SetRedChannel(DependencyObject o, int value)
    {
        o.SetValue(RedChannelProperty, value);
    }

    public static void SetGreenChannel(DependencyObject o, int value)
    {
        o.SetValue(GreenChannelProperty, value);
    }

    public static void SetBlueChannel(DependencyObject o, int value)
    {
        o.SetValue(BlueChannelProperty, value);
    }

    public static void SetAlphaChannel(DependencyObject o, int value)
    {
        o.SetValue(AlphaChannelProperty, value);
    }

    public static void SetBrush(DependencyObject o, SolidColorBrush brush)
    {
        o.SetValue(BrushProperty, brush);
    }

    public static void SetColourValue(DependencyObject o, string value)
    {
        o.SetValue(ColourValueProperty, value);
    }

    private static void DoColorChangedRed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
        DoColorChange(d, (int)e.NewValue, c => c.R, () => Color.FromArgb(color.A, ((byte)(int)e.NewValue), color.G , color.B));
    }

    private static void DoColorChangedGreen(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
        DoColorChange(d, (int)e.NewValue, c => c.G, () => Color.FromArgb(color.A, color.R, ((byte)(int)e.NewValue), color.B));
    }

    private static void DoColorChangedBlue(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
        DoColorChange(d, (int)e.NewValue, c => c.B, () => Color.FromArgb(color.A, color.R, color.G, (byte)(int)e.NewValue));
    }

    private static void DoColorChangedAlpha(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
        DoColorChange(d, (int)e.NewValue, c => c.A, () => Color.FromArgb((byte)(int)e.NewValue, color.R, color.G, color.B));
    }

    private static void DoColorChange(DependencyObject d, int newValue, Func<Color, int> colorCompare, Func<Color> getColor)
    {
        var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
        if (colorCompare(color) == newValue)
            return;
        var newBrush = new SolidColorBrush(getColor());
        d.SetValue(BrushProperty, newBrush);
        d.SetValue(ColourValueProperty, newBrush.Color.ToString());
    }

    private static void DoValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
        if (color.ToString() == (string)e.NewValue)
            return;
        Color? newColour = null;
        try
        {
            newColour = (Color) ColorConverter.ConvertFromString((string) e.NewValue);
        }
        catch{}
        if (newColour == null)
            return;
        var newBrush = new SolidColorBrush(newColour.Value);
        d.SetValue(BrushProperty, newBrush);
    }


    private static void DoBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue == e.OldValue)
            return;
        var colour = ((SolidColorBrush)e.NewValue).Color;
        d.SetValue(RedChannelProperty,(int)colour.R);
        d.SetValue(GreenChannelProperty,(int)colour.G);
        d.SetValue(BlueChannelProperty,(int)colour.B);
        d.SetValue(AlphaChannelProperty,(int)colour.A);
        d.SetValue(ColourValueProperty,colour.ToString());
    }
}

这是它的使用方式

<Window x:Class="ChannelColourBrush.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:c="clr-namespace:ChannelColourBrush" Title="Window1" Height="300" Width="300">
<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="Auto" />
  </Grid.ColumnDefinitions>
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <TextBlock Text="Red" />
  <TextBlock Text="Green" Grid.Row="1" />
  <TextBlock Text="Blue" Grid.Row="2" />
  <TextBlock Text="Alpha" Grid.Row="3" />

  <Slider Name="redSlider" Grid.Column="1" Minimum="0" Maximum="255"  Width="200" Height="20" Grid.ColumnSpan="2" Value="{Binding ElementName=rect, Path=(c:BrushExtender.RedChannel), Mode=TwoWay}" />
  <Slider Name="greenSlider" Grid.Column="1" Grid.Row="1" Minimum="0" Maximum="255" Width="200" Height="20" Grid.ColumnSpan="2" Value="{Binding ElementName=rect, Path=(c:BrushExtender.GreenChannel), Mode=TwoWay}"  />
  <Slider Name="blueSlider" Grid.Column="1" Grid.Row="2" Minimum="0" Maximum="255" Width="200" Height="20" Grid.ColumnSpan="2" Value="{Binding ElementName=rect, Path=(c:BrushExtender.BlueChannel), Mode=TwoWay}"  />
  <Slider Name="alphaSlider" Grid.Column="1" Grid.Row="3" Minimum="0" Maximum="255" Width="200" Height="20" Grid.ColumnSpan="2" Value="{Binding ElementName=rect, Path=(c:BrushExtender.AlphaChannel), Mode=TwoWay}"  />

  <Rectangle Fill="SandyBrown" Name="rect" Width="200" Height="50" Grid.Row="4" Grid.ColumnSpan="3" Margin="0,20,0,10"
    c:BrushExtender.Brush="{Binding RelativeSource={RelativeSource Self}, Path=Fill, Mode=TwoWay}"/>
  <TextBlock Text="Colour Value" Margin="5,0,5,0" Grid.Row="5" HorizontalAlignment="Center"  />
  <TextBox Text="{Binding ElementName=rect, Path=(c:BrushExtender.ColourValue), Mode=TwoWay}" Margin="0,0,0,0" Grid.Row="5" Grid.Column="1" Width="100" HorizontalAlignment="Center" />
  <Button Content="Update" IsEnabled="{Binding ElementName=grid, Path=SelectedItem.SomeValue}"/>
</Grid>


3

您可以轻松地使用来自经典Windows Forms的ColorDialog

using System.Windows.Forms;

ColorDialog colorDialog = new ColorDialog();

if (colorDialog.ShowDialog() == DialogResult.OK)
{
    // do some stuff with colors...
}

enter image description here


你可能需要向你的项目添加一个程序集引用(“System.Windows.Forms.dll”)。 - eikuh
如果你想要使用颜色,那么也需要使用 System.Drawing。 - eikuh

0

我被迫自己制作这样的对话框。请看WPFColorLib - 这是自由开源软件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接