使用滑块和依赖属性在C#中创建和使用新的画笔或颜色 [英] Creating and using a new Brush or color using sliders and dependency properties in C#

查看:612
本文介绍了使用滑块和依赖属性在C#中创建和使用新的画笔或颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个项目,这是一个基本的WPFPaint应用程序。我有三个选项,画一个椭圆,画一条线,或画一个形状(一个闭合的部分填充的线)。这三个选项用单选按钮表示。我已经到这部分工作。以下是示例屏幕截图:



http:/ /i.stack.imgur.com/naPyI.jpg



基本上,我现在需要做的是,当用户更改R,G ,B和A(不透明度/阿尔法),应当更新示出新颜色的小预览区域,并且该颜色应当被设置为线或填充颜色,这取决于哪组滑块被改变。 所有这一切都需要通过数据绑定完成。



我不确定如何最好地解决这个问题。我应该为每个滑块(RGBA)单独的值,并将这些值传递给Color.FromArgb(R,G,B,A)??



编辑:这是我的代码



使用System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
使用System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用System.Windows.Navigation;
使用System.Windows.Shapes;
using System.ComponentModel;

 命名空间WpfPaint 
{
public partial class MainWindow:Window ,INotifyPropertyChanged
{
public bool start = false;
public Ellipse myEllipse;
public Polyline myLine;
public Line myRegLine = new Line();
public double xPos;
public double yPos;

public MainWindow()
{
InitializeComponent();
MyCanvas.Children.Add(myRegLine);
}

private void MyCanvas_PreviewMouseDown(object sender,MouseButtonEventArgs e)
{
if(this.ellipse.IsChecked?false)
{
if(start)
{
start =!start;
myEllipse = null;
}
else
{
start = true;
myEllipse = new Ellipse();
xPos = e.GetPosition(MyCanvas).X;
yPos = e.GetPosition(MyCanvas).Y;

MyCanvas.Children.Add(myEllipse);
myEllipse.StrokeThickness = 5;
if(comboBox2.Text ==Red)
{
myEllipse.Fill = Brushes.Red;
fillR.Value = 255;
fillG.Value = 0;
fillB.Value = 0;
}
else if(comboBox2.Text ==Green)
{
myEllipse.Fill = Brushes.Green;
fillR.Value = 0;
fillG.Value = 255;
fillB.Value = 0;
}
else if(comboBox2.Text ==Blue)
{
myEllipse.Fill = Brushes.Blue;
fillR.Value = 0;
fillG.Value = 0;
fillB.Value = 255;
}

if(comboBox1.Text ==Red)
{
myEllipse.Stroke = Brushes.Red;
lineR.Value = 255;
lineG.Value = 0;
lineB.Value = 0;
}
else if(comboBox1.Text ==Green)
{
myEllipse.Stroke = Brushes.Green;
lineRValue = 0;
lineG.Value = 255;
lineB.Value = 0;
}
else if(comboBox1.Text ==Blue)
{
myEllipse.Stroke = Brushes.Blue;
lineR.Value = 0;
lineG.Value = 0;
lineB.Value = 255;
}
}
}
else
{
switch(e.ClickCount)
{
case 1:
if(myLine == null)
{
myLine = new Polyline();
MyCanvas.Children.Add(myLine);
myLine.StrokeThickness = 5;
if(comboBox1.Text ==Red)
{

myLine.Stroke = Brushes.Red;
lineR.Value = 255;
lineG.Value = 0;
lineB.Value = 0;
}
else if(comboBox1.Text ==Green)
{

myLine.Stroke = Brushes.Green;
lineR.Value = 0;
lineG.Value = 255;
lineB.Value = 0;
}
else if(comboBox1.Text ==Blue)
{

myLine.Stroke = Brushes.Blue;
lineR.Value = 0;
lineG.Value = 0;
lineB.Value = 255;
}

if(this.shape.IsChecked?false)
{
if(comboBox2.Text ==Red)
{
myLine.Fill = Brushes.Red;
fillR.Value = 255;
fillG.Value = 0;
fillB.Value = 0;
}
else if(comboBox2.Text ==Green)
{
myLine.Fill = Brushes.Green;
fillR.Value = 0;
fillG.Value = 255;
fillB.Value = 0;
}
else if(comboBox2.Text ==Blue)
{
myLine.Fill = Brushes.Blue;
fillR.Value = 0;
fillG.Value = 0
fillB.Value = 255;
}
}


}

myLine.Points.Add(e.GetPosition(MyCanvas));
e.Handled = true;

break;
case 2:
myLine = null;
myRegLine = new Line();
MyCanvas.Children.Add(myRegLine);
break;

}

}
}

private void MyCanvas_PreviewMouseMove(object sender,MouseEventArgs e)
{
if(start)
{
myEllipse.Height = Math.Abs​​(e.GetPosition(MyCanvas).X - xPos)* 2;
myEllipse.Width = Math.Abs​​(e.GetPosition(MyCanvas).X - xPos)* 2;

Canvas.SetTop(myEllipse,((yPos) - myEllipse.Height / 2));
Canvas.SetLeft(myEllipse,((xPos) - myEllipse.Width / 2));
}

else
{
if(myLine!= null)
{
myRegLine.Stroke = myLine.Stroke;
myRegLine.X1 = myLine.Points.Last()。X;
myRegLine.Y1 = myLine.Points.Last()。Y;
myRegLine.X2 = e.GetPosition(MyCanvas).X;
myRegLine.Y2 = e.GetPosition(MyCanvas).Y;
}
}
}

private void comboBox1_SelectionChanged(object sender,SelectionChangedEventArgs e)
{

}

private void comboBox2_SelectionChanged(object sender,SelectionChangedEventArgs e)
{

}
}
}



这里是我的XAML

  x:Class =WpfPaint.MainWindow
xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x =http://schemas.microsoft .com / winfx / 2006 / xaml
标题=MainWindowHeight =350Width =525>
< Grid>
< RadioButton Content =LineHeight =16Horizo​​ntalAlignment =LeftMargin =12,10,0,0Name =lineGroupName =optionsVerticalAlignment =TopIsChecked = True/>
< RadioButton Content =ShapeHeight =16Horizo​​ntalAlignment =LeftMargin =12,34,0,0Name =shapeGroupName =optionsVerticalAlignment =Top/> ;
< RadioButton Content =EllipseHeight =16Horizo​​ntalAlignment =LeftMargin =12,56,0,0Name =ellipseGroupName =optionsVerticalAlignment =Top/> ;
< Label Content =RMargin =210,5,270,0Height =31VerticalAlignment =Top/>
< Slider Height =23Horizo​​ntalAlignment =LeftMargin =229,5,0,0Name =lineRVerticalAlignment =TopWidth =50IsMoveToPointEnabled =FalseInterval = 1IsSelectionRangeEnabled =FalseMaximum =255/>
< Slider Height =23Margin =306,5,147,0Name =lineGVerticalAlignment =TopIsMoveToPointEnabled =FalseInterval =1Maximum =255/>
< Label Content =GMargin =282,3,203,0Height =30VerticalAlignment =Top/>
< Slider Height =23Horizo​​ntalAlignment =LeftMargin =380,5,0,0Name =lineBVerticalAlignment =TopWidth =50Interval =1 255/>
< Label Content =BMargin =358,3,129,280/>
< Slider Height =23Horizo​​ntalAlignment =LeftMargin =453,5,0,0Name =lineAVerticalAlignment =TopWidth =50Interval =1 255Value =255/>
< Label Content =AMargin =428,3,56,0Height =28VerticalAlignment =Top/>
< Canvas Name =MyCanvasBackground =#FFDADADAMargin =0,76,0,0PreviewMouseDown =MyCanvas_PreviewMouseDownPreviewMouseMove =MyCanvas_PreviewMouseMove>< / Canvas&
< ComboBox Height =23Horizo​​ntalAlignment =LeftMargin =127,5,0,0Name =comboBox1VerticalAlignment =TopWidth =70SelectionChanged =comboBox1_SelectionChanged>
< ComboBoxItem Content =RedIsSelected =True/>
< ComboBoxItem Content =Green/>
< ComboBoxItem Content =Blue/>
< / ComboBox>
< Label Content =LineHeight =28Horizo​​ntalAlignment =LeftMargin =89,3,0,0Name =label1VerticalAlignment =Top/&
< Label Content =FillHeight =28Horizo​​ntalAlignment =LeftMargin =96,42,0,0Name =label2VerticalAlignment =Top/&
< ComboBox Height =23Horizo​​ntalAlignment =LeftMargin =127,44,0,0Name =comboBox2VerticalAlignment =TopWidth =70SelectionChanged =comboBox2_SelectionChanged>
< ComboBoxItem Content =RedIsSelected =True/>
< ComboBoxItem Content =Green/>
< ComboBoxItem Content =Blue/>
< / ComboBox>
< Label Content =RMargin =210,42,270,238/>
< Slider Height =23Horizo​​ntalAlignment =LeftIsMoveToPointEnabled =FalseMargin =229,44,0,0Name =fillRVerticalAlignment =TopWidth =50 255Interval =1/>
< Slider Height =23Horizo​​ntalAlignment =LeftIsMoveToPointEnabled =FalseMargin =306,44,0,0Name =fillGVerticalAlignment =TopWidth =50 255Interval =1/>
< Label Content =GMargin =282,40,203,241/>
< Slider Height =23Horizo​​ntalAlignment =LeftMargin =380,44,0,0Name =fillBVerticalAlignment =TopWidth =50Maximum =255Interval = 1/>
< Label Content =BMargin =358,42,0,241Horizo​​ntalAlignment =LeftWidth =16/>
< Slider Height =23Horizo​​ntalAlignment =LeftMargin =453,44,0,0Name =fillAVerticalAlignment =TopWidth =50Value =255Interval = 1Maximum =255/>
< Label Content =AMargin =428,42,56,241/>
< / Grid>

解决方案>

不知道这是否是最好的方法,但你可以有5个公共属性在您的viewmodel:
一个为Alpha,一个为红色,一个为绿色,一个为蓝色,一个用户定义结构,您将使用它们将4个值组合在一起(我们称之为FillValue)。将4个滑块绑定到Alpha,Red,Green和Blue。在这些4属性的setters中,您在FillValue中设置相应的字段,然后为这两个属性调用NotifyPropertyChanged。像这样的:

  public double Red 
{
get {return FillValue.Red; }
set
{
FillValue.Red = value;
NotifyPropertyChanged(Red);
NotifyPropertyChanged(FillValue);
}
}

然后将预览的fill属性绑定到FillValue,转换器将FillValue转换为刷。绑定将如下所示:

 < StackPanel> 
< StackPanel.Resources>
< RGBExample:FillValueCvtr x:Key =ColorCvtr/>
< /StackPanel.Resources>

< Rectangle Fill ={Binding FillValue,Converter = {StaticResource ColorCvtr}}/>
< / StackPanel>


I'm working on a project which is a basic WPF "Paint" app. I have three options, draw an Ellipse, draw a Line, or draw a 'shape' (a line where closed sections are filled in). These three options are represented with radio buttons. I have up to this part working. Here's an example screenshot:

http://i.stack.imgur.com/naPyI.jpg

Basically what I need to do now is, when the user changes the sliders for R, G, B, and A (opacity / alpha), a small preview area showing the new color should be updated, and that color should be set as the line or fill color, depending on which group of sliders is changed. All of this needs to be done with data binding.

I'm not really sure as to to best approach this problem. Should I have individual values for each slider (RGBA) and pass those values into Color.FromArgb(R,G,B,A)??

EDIT: Here is my code

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.ComponentModel;

namespace WpfPaint
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public bool start = false;
        public Ellipse myEllipse;
        public Polyline myLine;
        public Line myRegLine = new Line();
        public double xPos;
        public double yPos;

        public MainWindow()
        {
            InitializeComponent();
            MyCanvas.Children.Add(myRegLine);
        }

        private void MyCanvas_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (this.ellipse.IsChecked ?? false)
            {
                if (start)
                {
                    start = !start;
                    myEllipse = null;
                }
                else
                {
                    start = true;
                    myEllipse = new Ellipse();
                    xPos = e.GetPosition(MyCanvas).X;
                    yPos = e.GetPosition(MyCanvas).Y;

                    MyCanvas.Children.Add(myEllipse);
                    myEllipse.StrokeThickness = 5;
                    if (comboBox2.Text == "Red")
                    {
                        myEllipse.Fill = Brushes.Red;
                        fillR.Value = 255;
                        fillG.Value = 0;
                        fillB.Value = 0;
                    }
                    else if (comboBox2.Text == "Green")
                    {
                        myEllipse.Fill = Brushes.Green;
                        fillR.Value = 0;
                        fillG.Value = 255;
                        fillB.Value = 0;
                    }
                    else if (comboBox2.Text == "Blue")
                    {
                        myEllipse.Fill = Brushes.Blue;
                        fillR.Value = 0;
                        fillG.Value = 0;
                        fillB.Value = 255;
                    }

                    if (comboBox1.Text == "Red")
                    {
                        myEllipse.Stroke = Brushes.Red;
                        lineR.Value = 255;
                        lineG.Value = 0;
                        lineB.Value = 0;
                    }
                    else if (comboBox1.Text == "Green")
                    {
                        myEllipse.Stroke = Brushes.Green;
                        lineR.Value = 0;
                        lineG.Value = 255;
                        lineB.Value = 0;
                    }
                    else if (comboBox1.Text == "Blue")
                    {
                        myEllipse.Stroke = Brushes.Blue;
                        lineR.Value = 0;
                        lineG.Value = 0;
                        lineB.Value = 255;
                    }
                }
            }
            else
            {
                switch (e.ClickCount)
                {
                    case 1:
                        if (myLine == null)
                        {
                            myLine = new Polyline();
                            MyCanvas.Children.Add(myLine);
                            myLine.StrokeThickness = 5;
                            if (comboBox1.Text == "Red")
                            {

                                myLine.Stroke = Brushes.Red;
                                lineR.Value = 255;
                                lineG.Value = 0;
                                lineB.Value = 0;
                            }
                            else if (comboBox1.Text == "Green")
                            {

                                myLine.Stroke = Brushes.Green;
                                lineR.Value = 0;
                                lineG.Value = 255;
                                lineB.Value = 0;
                            }
                            else if (comboBox1.Text == "Blue")
                            {

                                myLine.Stroke = Brushes.Blue;
                                lineR.Value = 0;
                                lineG.Value = 0;
                                lineB.Value = 255;                                
                            }

                            if (this.shape.IsChecked ?? false)
                            {
                                if (comboBox2.Text == "Red")
                                {                                    
                                    myLine.Fill = Brushes.Red;
                                    fillR.Value = 255;
                                    fillG.Value = 0;
                                    fillB.Value = 0;
                                }
                                else if (comboBox2.Text == "Green")
                                {                                    
                                    myLine.Fill = Brushes.Green;
                                    fillR.Value = 0;
                                    fillG.Value = 255;
                                    fillB.Value = 0;
                                }
                                else if (comboBox2.Text == "Blue")
                                {                                    
                                    myLine.Fill = Brushes.Blue;
                                    fillR.Value = 0;
                                    fillG.Value = 0;
                                    fillB.Value = 255;
                                }
                            }


                        }

                        myLine.Points.Add(e.GetPosition(MyCanvas));
                        e.Handled = true;

                        break;
                    case 2:
                        myLine = null;
                        myRegLine = new Line();
                        MyCanvas.Children.Add(myRegLine);
                        break;

                }

            }
        }

        private void MyCanvas_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (start)
            {
                myEllipse.Height = Math.Abs(e.GetPosition(MyCanvas).X - xPos) * 2;
                myEllipse.Width = Math.Abs(e.GetPosition(MyCanvas).X - xPos) * 2;

                Canvas.SetTop(myEllipse, ((yPos) - myEllipse.Height / 2));
                Canvas.SetLeft(myEllipse, ((xPos) - myEllipse.Width / 2));
            }

            else
            {
                if (myLine != null)
                {
                    myRegLine.Stroke = myLine.Stroke;
                    myRegLine.X1 = myLine.Points.Last().X;
                    myRegLine.Y1 = myLine.Points.Last().Y;
                    myRegLine.X2 = e.GetPosition(MyCanvas).X;
                    myRegLine.Y2 = e.GetPosition(MyCanvas).Y;
                }
            }
        }

        private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void comboBox2_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
    }
}

and here is my XAML

<Window x:Class="WpfPaint.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <RadioButton Content="Line" Height="16" HorizontalAlignment="Left" Margin="12,10,0,0" Name="line" GroupName="options" VerticalAlignment="Top" IsChecked="True" />
    <RadioButton Content="Shape" Height="16" HorizontalAlignment="Left" Margin="12,34,0,0" Name="shape" GroupName="options" VerticalAlignment="Top" />
    <RadioButton Content="Ellipse" Height="16" HorizontalAlignment="Left" Margin="12,56,0,0" Name="ellipse" GroupName="options" VerticalAlignment="Top" />
    <Label Content="R" Margin="210,5,270,0" Height="31" VerticalAlignment="Top" />
    <Slider Height="23" HorizontalAlignment="Left" Margin="229,5,0,0" Name="lineR" VerticalAlignment="Top" Width="50" IsMoveToPointEnabled="False" Interval="1" IsSelectionRangeEnabled="False" Maximum="255" />
    <Slider Height="23" Margin="306,5,147,0" Name="lineG" VerticalAlignment="Top" IsMoveToPointEnabled="False" Interval="1" Maximum="255" />
    <Label Content="G" Margin="282,3,203,0" Height="30" VerticalAlignment="Top" />
    <Slider Height="23" HorizontalAlignment="Left" Margin="380,5,0,0" Name="lineB" VerticalAlignment="Top" Width="50" Interval="1" Maximum="255" />
    <Label Content="B" Margin="358,3,129,280"/>
    <Slider Height="23" HorizontalAlignment="Left" Margin="453,5,0,0" Name="lineA" VerticalAlignment="Top" Width="50" Interval="1" Maximum="255" Value="255" />
    <Label Content="A" Margin="428,3,56,0" Height="28" VerticalAlignment="Top" />
    <Canvas Name="MyCanvas" Background="#FFDADADA" Margin="0,76,0,0" PreviewMouseDown="MyCanvas_PreviewMouseDown" PreviewMouseMove="MyCanvas_PreviewMouseMove"></Canvas>
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="127,5,0,0" Name="comboBox1" VerticalAlignment="Top" Width="70" SelectionChanged="comboBox1_SelectionChanged">
        <ComboBoxItem Content="Red" IsSelected="True" />
        <ComboBoxItem Content="Green" />
        <ComboBoxItem Content="Blue" />
    </ComboBox>
    <Label Content="Line" Height="28" HorizontalAlignment="Left" Margin="89,3,0,0" Name="label1" VerticalAlignment="Top" />
    <Label Content="Fill" Height="28" HorizontalAlignment="Left" Margin="96,42,0,0" Name="label2" VerticalAlignment="Top" />
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="127,44,0,0" Name="comboBox2" VerticalAlignment="Top" Width="70" SelectionChanged="comboBox2_SelectionChanged">
        <ComboBoxItem Content="Red" IsSelected="True" />
        <ComboBoxItem Content="Green" />
        <ComboBoxItem Content="Blue" />
    </ComboBox>
    <Label Content="R" Margin="210,42,270,238" />
    <Slider Height="23" HorizontalAlignment="Left" IsMoveToPointEnabled="False" Margin="229,44,0,0" Name="fillR" VerticalAlignment="Top" Width="50" Maximum="255" Interval="1" />
    <Slider Height="23" HorizontalAlignment="Left" IsMoveToPointEnabled="False" Margin="306,44,0,0" Name="fillG" VerticalAlignment="Top" Width="50" Maximum="255" Interval="1" />
    <Label Content="G" Margin="282,40,203,241" />
    <Slider Height="23" HorizontalAlignment="Left" Margin="380,44,0,0" Name="fillB" VerticalAlignment="Top" Width="50" Maximum="255" Interval="1" />
    <Label Content="B" Margin="358,42,0,241" HorizontalAlignment="Left" Width="16" />
    <Slider Height="23" HorizontalAlignment="Left" Margin="453,44,0,0" Name="fillA" VerticalAlignment="Top" Width="50" Value="255" Interval="1" Maximum="255" />
    <Label Content="A" Margin="428,42,56,241" />
</Grid>

解决方案

Not sure if this is the best way to do it but you can have 5 public properties in your viewmodel: one for Alpha, one for Red, one for Green, one for Blue, and one user defined structure that you will use to "group" the 4 values together (let's call it FillValue). Bind your 4 sliders to Alpha, Red, Green, and Blue. in the setters for those 4 properties, you set the corresponding field in FillValue then call NotifyPropertyChanged for both properties. Something like this:

    public double Red
    {
        get { return FillValue.Red; }
        set
        {
            FillValue.Red = value;
            NotifyPropertyChanged("Red");
            NotifyPropertyChanged("FillValue");
        }
    }

Then bind your preview's fill property to FillValue and add a converter to convert the FillValue to a brush. The binding will look something like this:

<StackPanel>    
    <StackPanel.Resources>
        <RGBExample:FillValueCvtr x:Key="ColorCvtr"/>
    </StackPanel.Resources>

    <Rectangle Fill="{Binding FillValue, Converter={StaticResource ColorCvtr}}"/>
</StackPanel>

这篇关于使用滑块和依赖属性在C#中创建和使用新的画笔或颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆