0

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>

4

1 回答 1

1

不确定这是否是最好的方法,但您的视图模型中可以有 5 个公共属性:一个用于 Alpha,一个用于红色,一个用于绿色,一个用于蓝色,以及一个用户定义的结构,您将用于“分组" 4 个值一起(我们称之为 FillValue)。将 4 个滑块绑定到 Alpha、Red、Green 和 Blue。在这 4 个属性的设置器中,您在 FillValue 中设置相应的字段,然后为这两个属性调用 NotifyPropertyChanged。像这样的东西:

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

然后将预览的填充属性绑定到 FillValue 并添加转换器以将 FillValue 转换为画笔。绑定将如下所示:

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

    <Rectangle Fill="{Binding FillValue, Converter={StaticResource ColorCvtr}}"/>
</StackPanel>
于 2010-11-16T14:12:25.873 回答