操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    WPF 實現顏色選擇器控件

    控件名:ColorPicker

    作 者:WPFDevelopersOrg - 黃佳 | 驚鏵

    原文鏈接[1]:https://github.com/WPFDevelopersOrg/WPFDevelopers

    • 框架使用.NET4 至 .NET6
    • Visual Studio 2022;

    1)新增 ColorPicker.cs 代碼如下:

    • 包含一個Slider(用于選擇色調)、一個Canvas(用于選擇飽和度和亮度)、一個Thumb(拖動選擇飽和度和亮度的指示器)和一個Button(用于切換顏色類型)。

    • 通過使用ColorPicker控件,用戶可以選擇一個顏色,并且可以通過綁定SelectedColor屬性來獲取所選顏色。這個屬性是一個依賴屬性,支持雙向綁定,并且當顏色發生改變時會觸發SelectedColorChanged事件。

    • ColorType屬性用于指定顏色類型,可以選擇RGB、HSL或HEX三種類型之一。當用戶點擊Button時,可以循環切換顏色類型。

    • 在控件的模板中,通過TemplatePart特性標記了四個重要的子元素:HueSlider、Canvas、Thumb和Button。在OnApplyTemplate方法中,根據模板找到這些子元素,并注冊相應的事件處理程序。

    • 控件通過使用顏色轉換工具類ColorUtil實現顏色的轉換和計算。當用戶在Canvas上點擊或拖動Thumb時,會計算得到相應的HSB(色調、飽和度、亮度)值,并將其設置為依賴屬性HSB的值。然后根據HSB的值計算出對應的顏色,并更新SelectedColor屬性的值。

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Controls.Primitives;
    using System.Windows.Input;
    using System.Windows.Media;
    using WPFDevelopers.Utilities;

    namespace WPFDevelopers.Controls
    {
    [TemplatePart(Name=HueSliderColorTemplateName, Type=typeof(Slider))]
    [TemplatePart(Name=CanvasTemplateName, Type=typeof(Canvas))]
    [TemplatePart(Name=ThumbTemplateName, Type=typeof(Thumb))]
    [TemplatePart(Name=ButtonTemplateName, Type=typeof(Button))]
    public class ColorPicker : Control
    {
    private const string HueSliderColorTemplateName="PART_HueSlider";

    private const string CanvasTemplateName="PART_Canvas";

    private const string ThumbTemplateName="PART_Thumb";

    private const string ButtonTemplateName="PART_Button";

    private static readonly DependencyPropertyKey HueColorPropertyKey=
    DependencyProperty.RegisterReadOnly("HueColor", typeof(Color), typeof(ColorPicker),
    new PropertyMetadata(Colors.Red));

    public static readonly DependencyProperty HueColorProperty=HueColorPropertyKey.DependencyProperty;

    public static readonly DependencyProperty SelectedColorProperty=
    DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorPicker),
    new FrameworkPropertyMetadata(Colors.Red, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
    OnSelectedColorChanged));

    private static readonly DependencyPropertyKey HSBPropertyKey=
    DependencyProperty.RegisterReadOnly("HSB", typeof(HSB), typeof(ColorPicker),
    new PropertyMetadata(new HSB()));

    public static readonly DependencyProperty HSBHProperty=HSBPropertyKey.DependencyProperty;

    public static readonly DependencyProperty ColorTypeProperty=
    DependencyProperty.Register("ColorType", typeof(ColorTypeEnum), typeof(ColorPicker),
    new PropertyMetadata(ColorTypeEnum.RGB));

    private Button _button;

    private Canvas _canvas;

    private Slider _hueSliderColor;

    private bool _isInnerUpdateSelectedColor;

    private Thumb _thumb;

    private ColorTypeEnum[] colorTypeEnums;

    private int currentGridStateIndex;


    static ColorPicker()
    {
    DefaultStyleKeyProperty.OverrideMetadata(typeof(ColorPicker),
    new FrameworkPropertyMetadata(typeof(ColorPicker)));
    }

    public Color HueColor=> (Color) GetValue(HueColorProperty);

    public Color SelectedColor
    {
    get=> (Color) GetValue(SelectedColorProperty);
    set=> SetValue(SelectedColorProperty, value);
    }

    public HSB HSB=> (HSB) GetValue(HSBHProperty);


    public ColorTypeEnum ColorType
    {
    get=> (ColorTypeEnum) GetValue(ColorTypeProperty);
    set=> SetValue(ColorTypeProperty, value);
    }

    private static void OnSelectedColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    var ctrl=d as ColorPicker;
    if (ctrl._isInnerUpdateSelectedColor)
    {
    ctrl._isInnerUpdateSelectedColor=false;
    return;
    }

    var color=(Color) e.NewValue;
    double h=0, s=0, b=0;
    ColorUtil.HsbFromColor(color, ref h, ref s, ref b);
    var hsb=new HSB {H=h, S=s, B=b};
    ctrl.SetValue(HueColorPropertyKey, ColorUtil.ColorFromHsb(hsb.H, 1, 1));
    ctrl.SetValue(HSBPropertyKey, hsb);
    Canvas.SetLeft(ctrl._thumb, s * ctrl._canvas.ActualWidth - ctrl._thumb.ActualWidth / 2);
    Canvas.SetTop(ctrl._thumb, (1 - b) * ctrl._canvas.ActualHeight - ctrl._thumb.ActualHeight / 2);
    ctrl._hueSliderColor.Value=1 - h;
    }

    public override void OnApplyTemplate()
    {
    base.OnApplyTemplate();
    if (_hueSliderColor !=)
    _hueSliderColor.ValueChanged -=HueSliderColor_OnValueChanged;
    _canvas=GetTemplateChild(CanvasTemplateName) as Canvas;
    if (_canvas !=)
    {
    _canvas.Loaded +=Canvas_Loaded;
    _canvas.MouseUp +=Canvas_MouseUp;
    }

    _thumb=GetTemplateChild(ThumbTemplateName) as Thumb;
    if (_thumb !=)
    _thumb.DragDelta +=Thumb_DragDelta;
    _hueSliderColor=GetTemplateChild(HueSliderColorTemplateName) as Slider;
    if (_hueSliderColor !=)
    _hueSliderColor.ValueChanged +=HueSliderColor_OnValueChanged;

    _button=GetTemplateChild(ButtonTemplateName) as Button;
    currentGridStateIndex=0;
    colorTypeEnums=(ColorTypeEnum[]) Enum.GetValues(typeof(ColorTypeEnum));
    if (_button !=)
    _button.Click +=Button_Click;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
    currentGridStateIndex=(currentGridStateIndex + 1) % colorTypeEnums.Length;
    ColorType=colorTypeEnums[currentGridStateIndex];
    }

    private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
    {
    var canvasPosition=e.GetPosition(_canvas);
    GetHSB(canvasPosition);
    }

    private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
    {
    var canvasPosition=e.GetPosition(_canvas);
    GetHSB(canvasPosition);
    }

    private void GetHSB(Point point, bool isMove=true)
    {
    var newLeft=point.X - _thumb.ActualWidth / 2;
    var newTop=point.Y - _thumb.ActualHeight / 2;
    var thumbW=_thumb.ActualWidth / 2;
    var thumbH=_thumb.ActualHeight / 2;
    var canvasRight=_canvas.ActualWidth - thumbW;
    var canvasBottom=_canvas.ActualHeight - thumbH;
    if (newLeft < -thumbW)
    newLeft=-thumbW;
    else if (newLeft > canvasRight)
    newLeft=canvasRight;
    if (newTop < -thumbH)
    newTop=-thumbH;
    else if (newTop > canvasBottom)
    newTop=canvasBottom;

    if (isMove)
    {
    Canvas.SetLeft(_thumb, newLeft);
    Canvas.SetTop(_thumb, newTop);
    }

    var hsb=new HSB
    {
    H=HSB.H, S=(newLeft + thumbW) / _canvas.ActualWidth,
    B=1 - (newTop + thumbH) / _canvas.ActualHeight
    };
    SetValue(HSBPropertyKey, hsb);
    var currentColor=ColorUtil.ColorFromAhsb(1, HSB.H, HSB.S, HSB.B);
    if (SelectedColor !=currentColor)
    {
    _isInnerUpdateSelectedColor=true;
    SelectedColor=currentColor;
    }
    }

    private void Thumb_DragDelta(object sender, DragDeltaEventArgs e)
    {
    var point=Mouse.GetPosition(_canvas);
    GetHSB(point);
    }

    private void Canvas_Loaded(object sender, RoutedEventArgs e)
    {
    var width=(int) _canvas.ActualWidth;
    var height=(int) _canvas.ActualHeight;
    var point=new Point(width - _thumb.ActualWidth / 2, -_thumb.ActualHeight / 2);
    Canvas.SetLeft(_thumb, point.X);
    Canvas.SetTop(_thumb, point.Y);
    var hsb=new HSB {H=_hueSliderColor.Value, S=HSB.S, B=HSB.B};
    SetValue(HSBPropertyKey, hsb);
    }

    private void HueSliderColor_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
    if (DoubleUtil.AreClose(HSB.H, e.NewValue))
    return;
    var hsb=new HSB {H=1 - e.NewValue, S=HSB.S, B=HSB.B};
    SetValue(HSBPropertyKey, hsb);
    SetValue(HueColorPropertyKey, ColorUtil.ColorFromHsb(HSB.H, 1, 1));

    var newLeft=Canvas.GetLeft(_thumb);
    var newTop=Canvas.GetTop(_thumb);
    var point=new Point(newLeft, newTop);
    GetHSB(point, false);
    }
    }

    public enum ColorTypeEnum
    {
    RGB,
    HSL,
    HEX
    }
    }

    2)新增 ColorPicker.xaml 代碼如下:

    • 在Canvas的背景中使用了DrawingBrush和DrawingGroup來創建漸變和幾何形狀。
    • 創建了一個線性漸變刷(LinearGradientBrush),漸變的起點是(0,0),終點是(1,0)。其中的GradientStop標簽指定了兩個漸變停止點,一個偏移量為0,顏色為白色,另一個偏移量為1,顏色綁定到了HueColor屬性。
    • 接下來,同樣方式創建了另一個線性漸變刷,漸變的起點是(0,0),終點是(0,1)。GradientStop指定了兩個漸變停止點,一個偏移量為0,顏色為透明("#00000000"),另一個偏移量為1,顏色為黑色。
    <ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:WPFDevelopers.Controls"
    xmlns:convert="clr-namespace:WPFDevelopers.Converts"
    xmlns:helpers="clr-namespace:WPFDevelopers.Helpers"
    xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
    xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options">

    <ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Basic/ControlBasic.xaml" />
    </ResourceDictionary.MergedDictionaries>

    <convert:ColorToBrushConverter x:Key="WD.ColorToBrushConverter" />
    <convert:ColorToRedConverter x:Key="WD.ColorToRedConverter" />
    <convert:ColorToGreenConverter x:Key="WD.ColorToGreenConverter" />
    <convert:ColorToBlueConverter x:Key="WD.ColorToBlueConverter" />
    <convert:ColorTypeToVisibilityConverter x:Key="WD.ColorTypeToVisibilityConverter" />
    <convert:ColorToStringConverter x:Key="WD.ColorToStringConverter" />
    <convert:HToColorConverter x:Key="WD.HToColorConverter" />
    <convert:SToColorConverter x:Key="WD.SToColorConverter" />
    <convert:LToColorConverter x:Key="WD.LToColorConverter" />

    <LinearGradientBrush x:Key="WD.ColorPickerRainbowBrush" po:Freeze="True">
    <GradientStop Color="#FF0000" />
    <GradientStop Offset="0.167" Color="#FF00FF" />
    <GradientStop Offset="0.334" Color="#0000FF" />
    <GradientStop Offset="0.501" Color="#00FFFF" />
    <GradientStop Offset="0.668" Color="#00FF00" />
    <GradientStop Offset="0.835" Color="#FFFF00" />
    <GradientStop Offset="1" Color="#FF0000" />
    </LinearGradientBrush>

    <ControlTemplate x:Key="WD.ColorPickerSliderThumbTemplate" TargetType="Thumb">
    <Border
    Width="{TemplateBinding Width}"
    Height="{TemplateBinding Height}"
    Background="Transparent"
    BorderBrush="White"
    BorderThickness="3"
    CornerRadius="{Binding ActualWidth, RelativeSource={RelativeSource Self}, Converter={StaticResource WD.HalfValueConverter}}" />

    </ControlTemplate>


    <Style x:Key="WD.ColorPickerSliderRepeatButtonBaseStyle" TargetType="RepeatButton">
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Focusable" Value="false" />
    <Setter Property="IsTabStop" Value="false" />
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="RepeatButton">
    <Rectangle
    Width="{TemplateBinding Width}"
    Height="{TemplateBinding Height}"
    Fill="{TemplateBinding Background}" />

    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>



    <Style x:Key="WD.ColorPickerSlider" TargetType="{x:Type Slider}">
    <Setter Property="Background" Value="{StaticResource WD.ColorPickerRainbowBrush}" />
    <Setter Property="Stylus.IsPressAndHoldEnabled" Value="false" />
    <Setter Property="Orientation" Value="Horizontal" />
    <Setter Property="Height" Value="15" />
    <Setter Property="Margin" Value="4,0" />
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type Slider}">
    <controls:SmallPanel>
    <Border
    MaxWidth="{TemplateBinding MaxWidth}"
    Margin="{TemplateBinding Margin}"
    Background="{TemplateBinding Background}"
    CornerRadius="2" />

    <Track x:Name="PART_Track" Orientation="{TemplateBinding Orientation}">
    <Track.DecreaseRepeatButton>
    <RepeatButton Command="{x:Static Slider.DecreaseLarge}" Style="{StaticResource WD.ColorPickerSliderRepeatButtonBaseStyle}" />
    </Track.DecreaseRepeatButton>
    <Track.IncreaseRepeatButton>
    <RepeatButton Command="{x:Static Slider.IncreaseLarge}" Style="{StaticResource WD.ColorPickerSliderRepeatButtonBaseStyle}" />
    </Track.IncreaseRepeatButton>
    <Track.Thumb>
    <Thumb
    x:Name="Thumb"
    Width="15"
    Height="15"
    Focusable="False"
    OverridesDefaultStyle="True"
    Template="{StaticResource WD.ColorPickerSliderThumbTemplate}">

    <Thumb.Effect>
    <DropShadowEffect Opacity=".6" ShadowDepth="0" />
    </Thumb.Effect>
    </Thumb>
    </Track.Thumb>
    </Track>
    </controls:SmallPanel>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>


    <Style
    x:Key="WD.ColorPicker"
    BasedOn="{StaticResource WD.ControlBasicStyle}"
    TargetType="{x:Type controls:ColorPicker}">

    <Setter Property="Width" Value="260" />
    <Setter Property="Height" Value="200" />
    <Setter Property="Margin" Value="2" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="BorderBrush" Value="{DynamicResource WD.BaseSolidColorBrush}" />
    <Setter Property="Background" Value="{DynamicResource WD.BackgroundSolidColorBrush}" />
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="{x:Type controls:ColorPicker}">
    <Border
    Margin="{TemplateBinding Margin}"
    Background="{TemplateBinding Background}"
    BorderBrush="{TemplateBinding BorderBrush}"
    BorderThickness="{TemplateBinding BorderThickness}">

    <Grid>
    <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Canvas
    x:Name="PART_Canvas"
    Margin="1,1,1,0"
    ClipToBounds="True">

    <Canvas.Background>
    <DrawingBrush>
    <DrawingBrush.Drawing>
    <DrawingGroup>
    <GeometryDrawing>
    <GeometryDrawing.Brush>
    <LinearGradientBrush EndPoint="1,0">
    <GradientStop Offset="0" Color="White" />
    <GradientStop Offset="1" Color="{Binding HueColor, RelativeSource={RelativeSource TemplatedParent}}" />
    </LinearGradientBrush>
    </GeometryDrawing.Brush>
    <GeometryDrawing.Geometry>
    <RectangleGeometry Rect="0,0,5,5" />
    </GeometryDrawing.Geometry>
    </GeometryDrawing>
    <GeometryDrawing>
    <GeometryDrawing.Brush>
    <LinearGradientBrush EndPoint="0,1">
    <GradientStop Offset="0" Color="#00000000" />
    <GradientStop Offset="1" Color="{StaticResource WD.BlackColor}" />
    </LinearGradientBrush>
    </GeometryDrawing.Brush>
    <GeometryDrawing.Geometry>
    <RectangleGeometry Rect="0,0,5,5" />
    </GeometryDrawing.Geometry>
    </GeometryDrawing>
    </DrawingGroup>
    </DrawingBrush.Drawing>
    </DrawingBrush>
    </Canvas.Background>
    <Thumb
    x:Name="PART_Thumb"
    Width="15"
    Height="15"
    Background="Transparent"
    BorderBrush="White"
    BorderThickness="3">

    <Thumb.Template>
    <ControlTemplate TargetType="{x:Type Thumb}">
    <controls:SmallPanel>
    <Border
    Background="{TemplateBinding Background}"
    BorderBrush="{TemplateBinding BorderBrush}"
    BorderThickness="{TemplateBinding BorderThickness}"
    CornerRadius="{Binding ActualWidth, RelativeSource={RelativeSource Self}, Converter={StaticResource WD.HalfValueConverter}}"
    SnapsToDevicePixels="True">

    <Border.Effect>
    <DropShadowEffect Opacity=".6" ShadowDepth="0" />
    </Border.Effect>
    </Border>
    </controls:SmallPanel>
    </ControlTemplate>
    </Thumb.Template>
    </Thumb>
    </Canvas>
    <Grid Grid.Row="1" Margin="6,5,6,0">
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Ellipse
    Width="25"
    Height="25"
    Margin="0,0,4,0"
    Fill="{TemplateBinding SelectedColor,
    Converter={StaticResource WD.ColorToBrushConverter}}"
    >

    <Ellipse.Effect>
    <DropShadowEffect Opacity=".6" ShadowDepth="0" />
    </Ellipse.Effect>
    </Ellipse>
    <Slider
    Name="PART_HueSlider"
    Grid.Column="1"
    Width="Auto"
    IsMoveToPointEnabled="True"
    LargeChange="0.01"
    Maximum="1"
    SmallChange="0.01"
    Style="{StaticResource WD.ColorPickerSlider}"
    Value="1" />

    </Grid>
    <Grid
    Grid.Row="2"
    Margin="4"
    VerticalAlignment="Center">

    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.Resources>
    <Style TargetType="{x:Type StackPanel}">
    <Setter Property="Margin" Value="4,0" />
    </Style>
    <Style
    x:Key="WD.TextBoxColorPicker"
    BasedOn="{StaticResource WD.DefaultTextBox}"
    TargetType="{x:Type TextBox}">

    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="TextAlignment" Value="Center" />
    <Setter Property="Width" Value="50" />
    </Style>
    <Style BasedOn="{StaticResource WD.NumericBox}" TargetType="{x:Type controls:NumericBox}">
    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="TextAlignment" Value="Center" />
    <Setter Property="Width" Value="50" />
    <Setter Property="UpDownButtonsWidth" Value="0" />
    <Setter Property="Maximum" Value="255" />
    <Setter Property="Minimum" Value="0" />
    </Style>
    <Style TargetType="{x:Type TextBlock}">
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="Foreground" Value="{DynamicResource WD.PrimaryTextSolidColorBrush}" />
    <Setter Property="FontSize" Value="10" />
    </Style>
    </Grid.Resources>

    <Button
    Name="PART_Button"
    Grid.Column="0"
    Width="30"
    Height="30"
    Margin="0,0,4,0"
    helpers:ElementHelper.IsRound="True"
    Style="{StaticResource WD.NormalButton}">

    <controls:PathIcon Kind="UnfoldMore" />
    </Button>

    <UniformGrid
    Grid.Column="1"
    Rows="1"
    Visibility="{Binding ColorType, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.ColorTypeToVisibilityConverter}, ConverterParameter={x:Static controls:ColorTypeEnum.RGB}}">

    <StackPanel>
    <controls:NumericBox Value="{Binding SelectedColor, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.ColorToRedConverter}}" />
    <TextBlock Text="R" />
    </StackPanel>
    <StackPanel>
    <controls:NumericBox Value="{Binding SelectedColor, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.ColorToGreenConverter}}" />
    <TextBlock Text="G" />
    </StackPanel>
    <StackPanel>
    <controls:NumericBox Value="{Binding SelectedColor, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.ColorToBlueConverter}}" />
    <TextBlock Text="B" />
    </StackPanel>
    </UniformGrid>

    <UniformGrid
    Grid.Column="1"
    Rows="1"
    Visibility="{Binding ColorType, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.ColorTypeToVisibilityConverter}, ConverterParameter={x:Static controls:ColorTypeEnum.HSL}}">

    <StackPanel>
    <TextBox
    helpers:TextBoxHelper.AllowOnlyNumericInput="True"
    helpers:TextBoxHelper.IsEnterUpdateEnabled="True"
    helpers:TextBoxHelper.SelectAllOnClick="True"
    Style="{StaticResource WD.TextBoxColorPicker}"
    Text="{Binding SelectedColor, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.HToColorConverter}}" />

    <TextBlock Text="H" />
    </StackPanel>
    <StackPanel Grid.Column="1">
    <TextBox
    helpers:TextBoxHelper.IsEnterUpdateEnabled="True"
    helpers:TextBoxHelper.SelectAllOnClick="True"
    Style="{StaticResource WD.TextBoxColorPicker}"
    Text="{Binding SelectedColor, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.SToColorConverter}}" />

    <TextBlock Text="S" />
    </StackPanel>
    <StackPanel Grid.Column="2">
    <TextBox
    helpers:TextBoxHelper.IsEnterUpdateEnabled="True"
    helpers:TextBoxHelper.SelectAllOnClick="True"
    Style="{StaticResource WD.TextBoxColorPicker}"
    Text="{Binding SelectedColor, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.LToColorConverter}}" />

    <TextBlock Text="L" />
    </StackPanel>
    </UniformGrid>
    <StackPanel
    Grid.Column="1"
    Margin="12,0"
    Visibility="{Binding ColorType, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.ColorTypeToVisibilityConverter}, ConverterParameter={x:Static controls:ColorTypeEnum.HEX}}">

    <TextBox
    helpers:TextBoxHelper.IsEnterUpdateEnabled="True"
    helpers:TextBoxHelper.SelectAllOnClick="True"
    MaxLength="9"
    Text="{Binding SelectedColor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource WD.ColorToStringConverter}}"
    TextAlignment="Center" />

    <TextBlock Text="HEX" />
    </StackPanel>
    </Grid>
    </Grid>
    </Border>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>
    <Style BasedOn="{StaticResource WD.ColorPicker}" TargetType="{x:Type controls:ColorPicker}" />
    </ResourceDictionary>

    3)新增顏色轉換工具類 ColorUtil.cs 代碼如下:

    • 包含了將 HSL 顏色空間轉換為 RGB 顏色空間以及將 RGB 顏色空間轉換為 HSL 顏色空間的方法。
    • ConvertHSLToColor 方法用于將 HSL 顏色轉換為 RGB 顏色。HSLToRgb 方法實現了將 HSL 顏色轉換為 RGB 顏色的算法,而 SetColor 方法用于在計算過程中設置顏色值。
    • RgbToHSL 方法用于將 RGB 顏色轉換為 HSL 顏色。HsbFromColor 方法則實現了從 RGB 顏色獲取 HSB(色相、飽和度、亮度)的算法,并修改了傳入的引用類型參數。ColorFromAhsb 和 ColorFromHsb 方法分別用于根據 AHSB(透明度、色相、飽和度、亮度)和 HSB 值創建顏色對象。
    using System;
    using System.Windows.Media;
    using WPFDevelopers.Controls;

    namespace WPFDevelopers.Utilities
    {
    public static class ColorUtil
    {
    public static Color ConvertHSLToColor(Color color, double h=double.NaN, double sl=double.NaN,
    double l=double.NaN
    )

    {
    var hsl=RgbToHSL(color);
    if (!double.IsNaN(h))
    hsl.H=h;
    if (!double.IsNaN(sl))
    hsl.S=sl;
    if (!double.IsNaN(l))
    hsl.L=l;
    var rgb=HSLToRgb(hsl);
    return rgb;
    }

    private static Color HSLToRgb(HSL hslColor)
    {
    var rgbColor=new Color();
    if (hslColor.S==0)
    {
    rgbColor.R=(byte) (hslColor.L * 255);
    rgbColor.G=(byte) (hslColor.L * 255);
    rgbColor.B=(byte) (hslColor.L * 255);
    rgbColor.A=(byte) (hslColor.A * 255);
    return rgbColor;
    }

    double t1;
    if (hslColor.L < 0.5)
    t1=hslColor.L * (1.0 + hslColor.S);
    else
    t1=hslColor.L + hslColor.S - hslColor.L * hslColor.S;

    var t2=2.0 * hslColor.L - t1;

    var h=hslColor.H / 360;

    var tR=h + 1.0 / 3.0;
    var r=SetColor(t1, t2, tR);

    var tG=h;
    var g=SetColor(t1, t2, tG);

    var tB=h - 1.0 / 3.0;
    var b=SetColor(t1, t2, tB);

    rgbColor.R=(byte) (r * 255);
    rgbColor.G=(byte) (g * 255);
    rgbColor.B=(byte) (b * 255);
    rgbColor.A=(byte) (hslColor.A * 255);

    return rgbColor;
    }

    private static double SetColor(double t1, double t2, double t3)
    {
    if (t3 < 0) t3 +=1.0;
    if (t3 > 1) t3 -=1.0;

    double color;
    if (6.0 * t3 < 1)
    color=t2 + (t1 - t2) * 6.0 * t3;
    else if (2.0 * t3 < 1)
    color=t1;
    else if (3.0 * t3 < 2)
    color=t2 + (t1 - t2) * (2.0 / 3.0 - t3) * 6.0;
    else
    color=t2;
    return color;
    }

    public static HSL RgbToHSL(Color rgbColor)
    {
    var hslColor=new HSL();
    var r=(double) rgbColor.R / 255;
    var g=(double) rgbColor.G / 255;
    var b=(double) rgbColor.B / 255;
    var a=(double) rgbColor.A / 255;

    var min=Math.Min(r, Math.Min(g, b));
    var max=Math.Max(r, Math.Max(g, b));
    var delta=max - min;


    if (max==min)
    {
    hslColor.H=0;
    hslColor.S=0;
    hslColor.L=max;
    return hslColor;
    }

    hslColor.L=(min + max) / 2;

    if (hslColor.L < 0.5)
    hslColor.S=delta / (max + min);
    else
    hslColor.S=delta / (2.0 - max - min);

    if (r==max) hslColor.H=(g - b) / delta;
    if (g==max) hslColor.H=2.0 + (b - r) / delta;
    if (b==max) hslColor.H=4.0 + (r - g) / delta;
    hslColor.H *=60;
    if (hslColor.H < 0) hslColor.H +=360;

    hslColor.A=a;

    return hslColor;
    }

    public static void HsbFromColor(Color C, ref double H, ref double S, ref double B)
    {
    var r=C.R / 255d;
    var g=C.G / 255d;
    var b=C.B / 255d;

    var max=Math.Max(Math.Max(r, g), b);
    var min=Math.Min(Math.Min(r, g), b);
    var delta=max - min;

    var hue=0d;
    var saturation=DoubleUtil.GreaterThan(max, 0) ? delta / max : 0.0;
    var brightness=max;

    if (!DoubleUtil.IsZero(delta))
    {
    if (DoubleUtil.AreClose(r, max))
    hue=(g - b) / delta;
    else if (DoubleUtil.AreClose(g, max))
    hue=2 + (b - r) / delta;
    else if (DoubleUtil.AreClose(b, max))
    hue=4 + (r - g) / delta;

    hue=hue * 60;
    if (DoubleUtil.LessThan(hue, 0d))
    hue +=360;
    }

    H=hue / 360d;
    S=saturation;
    B=brightness;
    }

    public static Color ColorFromAhsb(double a, double h, double s, double b)
    {
    var r=ColorFromHsb(h, s, b);
    r.A=(byte) Math.Round(a * 255d);

    return r;
    }

    public static Color ColorFromHsb(double H, double S, double B)
    {
    double red=0.0, green=0.0, blue=0.0;

    if (DoubleUtil.IsZero(S))
    {
    red=green=blue=B;
    }
    else
    {
    var h=DoubleUtil.IsOne(H) ? 0d : H * 6.0;
    var i=(int) Math.Floor(h);

    var f=h - i;
    var r=B * (1.0 - S);
    var s=B * (1.0 - S * f);
    var t=B * (1.0 - S * (1.0 - f));

    switch (i)
    {
    case 0:
    red=B;
    green=t;
    blue=r;
    break;
    case 1:
    red=s;
    green=B;
    blue=r;
    break;
    case 2:
    red=r;
    green=B;
    blue=t;
    break;
    case 3:
    red=r;
    green=s;
    blue=B;
    break;
    case 4:
    red=t;
    green=r;
    blue=B;
    break;
    case 5:
    red=B;
    green=r;
    blue=s;
    break;
    }
    }

    return Color.FromRgb((byte) Math.Round(red * 255.0), (byte) Math.Round(green * 255.0),
    (byte) Math.Round(blue * 255.0));
    }
    }

    }

    4)示例 代碼如下:

    xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
    <wd:ColorPicker />

    參考資料

    [1]

    原文鏈接: https://github.com/WPFDevelopersOrg/WPFDevelopers

    WPF快速入門:構建現代桌面應用程序的指南

    WPF(Windows Presentation Foundation)是微軟的一個用于構建桌面客戶端應用程序的UI框架。它提供了一套豐富的控件和工具,使得開發者能夠創建出富有吸引力和高度交互性的用戶界面。本文將帶你快速入門WPF,并通過簡單的示例代碼,讓你了解WPF的基本概念和操作。

    環境搭建

    在開始WPF開發之前,你需要確保你的開發環境已經配置妥當。你需要安裝Visual Studio,這是微軟的集成開發環境(IDE),它提供了WPF項目模板和必要的工具。

    第一個WPF應用程序

    1. 打開Visual Studio,選擇“創建新項目”。
    2. 在項目類型中選擇“WPF App”。
    3. 填寫項目名稱和位置,點擊“創建”。

    XAML基礎

    XAML(Extensible Application Markup Language)是WPF使用的標記語言,用于定義用戶界面。在MainWindow.xaml文件中,你可以找到WPF應用程序的主窗口布局。

    控件

    WPF提供了一系列內置控件,如按鈕、文本框、標簽等。你可以通過XAML來聲明這些控件,并設置它們的屬性。

    事件處理

    WPF支持事件驅動編程模型。你可以為控件的事件編寫事件處理程序,以響應用戶的交互。

    數據綁定

    WPF的數據綁定機制允許你將UI元素與數據源緊密關聯,實現數據的動態更新。

    資源和樣式

    WPF允許你定義資源和樣式,以實現UI的統一和重用。

    MVVM模式

    MVVM(Model-View-ViewModel)是WPF中常用的設計模式,它有助于分離業務邏輯、用戶界面和數據模型。

    第一個WPF應用程序示例

    下面是一個簡單的WPF應用程序示例,它包含一個按鈕和一個文本框。當用戶點擊按鈕時,文本框中的文本將會改變。

    MainWindow.xaml

    <Window x:Class="WpfApp.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="WPF Demo" Height="200" Width="300">
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBox x:Name="textBox" Width="200" Height="20" Margin="5"/>
            <Button Content="Change Text" Width="80" Height="25" Margin="5" Click="Button_Click"/>
        </StackPanel>
    </Window>
    

    MainWindow.xaml.cs

    using System.Windows;
    
    namespace WpfApp
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                textBox.Text="Hello, WPF!";
            }
        }
    }
    

    在上面的示例中,我們創建了一個簡單的WPF應用程序,它包含一個文本框和一個按鈕。在XAML文件中,我們定義了UI布局,并為按鈕的Click事件綁定了一個事件處理程序。在C#代碼后面,我們實現了Button_Click方法,當用戶點擊按鈕時,它會更改文本框中的文本。

    總結

    本教程提供了一個WPF快速入門的概覽,介紹了WPF的基本概念和操作。通過簡單的示例,你可以開始探索WPF的強大功能,并構建自己的WPF應用程序。隨著實踐的深入,你將能夠利用WPF的高級特性,如數據綁定、樣式和動畫,來創建更加復雜和動態的用戶界面。

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有