Для выбора цвета нужен привычный колордиалог, но в Silverligth3 его нету, проблему решить очень просто, за основу взял статью и код
http://www.shinedraw.com/mathematics/first-silverlight-2-application-color-picker/
но эта версия работает под silverkigth2 и требуется в доработке под мой проект:
нужно сделать диалоговое окно тут я выбрал ChildWindow назвал его ColorDialog
<controls:ChildWindow x:Class="WebPiket2.Views.ColorDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
Width="549" Height="454"
Title="ColorDialog">
<Grid x:Name="LayoutRoot" Margin="2">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="CancelButton" Content="Отмена" Click="CancelButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1" />
<Button x:Name="OKButton" Content="ОК" Click="OKButton_Click" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1" />
<Grid Height="513" HorizontalAlignment="Left" Margin="6,7,0,0" Name="grid1" VerticalAlignment="Top" Width="639" >
<Canvas x:Name="LayoutColorControl" Background="White" Margin="0,0,118,137" MouseMove="RootVisual_MouseMove" MouseLeftButtonUp="Picker_MouseLeftButtonUp">
<!-- OldColor/NewColor -->
<Border Canvas.Left="100" Canvas.Top="30" Padding="2" BorderBrush="Black" BorderThickness="1">
<StackPanel Orientation="Horizontal">
<Canvas x:Name="OldColor" Width="165" Height="50" Background="#55FF0000"></Canvas>
<Canvas x:Name="NewColor" Width="165" Height="50" Background="#55FF00FF"></Canvas>
</StackPanel>
</Border>
<!-- ColorBoard -->
<Border Canvas.Left="100" Canvas.Top="100" Padding="2" BorderBrush="Black" BorderThickness="1">
<Grid Width="250" Height="250" x:Name="ColorBoard" MouseLeftButtonDown="Picker_MouseLeftButtonDown" >
<Canvas>
<Canvas.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<GradientStop Color="#FFFF0000" Offset="0"/>
<GradientStop Color="#FFFFFF00" Offset="0.16"/>
<GradientStop Color="#FF00FF00" Offset="0.33"/>
<GradientStop Color="#FF00FFFF" Offset="0.50"/>
<GradientStop Color="#FF0000FF" Offset="0.67"/>
<GradientStop Color="#FFFF00FF" Offset="0.83"/>
<GradientStop Color="#FFFF0000" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
</Canvas>
<Canvas>
<Canvas.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#00333333" Offset="0"/>
<GradientStop Color="#FF333333" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
</Canvas>
<Canvas>
<Ellipse x:Name="Picker" Width="12" Height="12" Stroke="Black" Fill="#CCFFFFFF" StrokeThickness="1" Canvas.Left="50" Canvas.Top="50">
<Ellipse.RenderTransform>
<TranslateTransform X="-6" Y="-6"></TranslateTransform>
</Ellipse.RenderTransform>
</Ellipse>
</Canvas>
</Grid>
</Border>
<!-- Gradient -->
<Border Canvas.Left="380" Canvas.Top="100" Padding="2" BorderBrush="Black" BorderThickness="1">
<Grid Width="50" Height="250" x:Name="Gradient" MouseLeftButtonDown="Gradient_MouseLeftButtonDown">
<Canvas Background="Red" x:Name="GradientBox">
</Canvas>
<Canvas>
<Canvas.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFFFFFFF" Offset="0"/>
<GradientStop Color="#00FFFFFF" Offset="0.5"/>
<GradientStop Color="#00000000" Offset="0.5"/>
<GradientStop Color="#FF000000" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
</Canvas>
<Canvas>
<Border x:Name="LightPicker" BorderBrush="White" BorderThickness="1">
<Canvas Background="Black" Height="4" Width="48"/>
</Border>
</Canvas>
</Grid>
</Border>
</Canvas>
</Grid>
</Grid>
</controls:ChildWindow>
Код был изменен, ссылки на обработчики событий вынесены в XAML
/****************************************************************************
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-- Copyright 2009 Terence Tsang
-- admin@shinedraw.com
-- http://www.shinedraw.com
-- Your Flash vs Silverlight Repositry
****************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace WebPiket2.Views
{
public partial class ColorDialog : ChildWindow
{
public ColorDialog()
{
InitializeComponent();
// Allow to use The RootVisual Object after Loaded
Loaded += new RoutedEventHandler(ColorPicker_Loaded);
}
public Color Result = new Color();
public string call = "";
private void OKButton_Click(object sender, RoutedEventArgs e)
{
SolidColorBrush br = (SolidColorBrush)NewColor.Background;
Result = br.Color;
this.DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
#region ColorPicker
private double[] _hsl = { 0, 0, 0.5 };
// New HSL Value
private double[] _tempHsl = { 0, 0, 0.5 };
// Check the Mouse Down
private bool _isBoardMouseDown = false;
private bool _isGradientMouseDown = false;
// Add Handlers
void ColorPicker_Loaded(object sender, RoutedEventArgs e)
{
// update color
showColor(_hsl, _tempHsl);
}
/////////////////////////////////////////////////////
// Handlers
/////////////////////////////////////////////////////
// Calculate the New Color Value
void RootVisual_MouseMove(object sender, MouseEventArgs e)
{
if (_isBoardMouseDown) // if change the hue and saturation
{
double offsetWidth = ColorBoard.ActualWidth;
double offsetHeight = ColorBoard.ActualHeight;
double mouseX = e.GetPosition(ColorBoard).X;
double mouseY = e.GetPosition(ColorBoard).Y;
// calculate new hue value
double hue = mouseX / offsetWidth;
hue = Math.Min(1, Math.Max(0, hue));
// calculate new saturation value
double saturation = 1 - mouseY / offsetHeight;
saturation = Math.Min(1, Math.Max(0, saturation));
// update the picker position
Picker.SetValue(Canvas.LeftProperty, hue * offsetWidth);
Picker.SetValue(Canvas.TopProperty, (1 - saturation ) * offsetHeight);
_tempHsl[0] = hue * 359;
_tempHsl[1] = saturation;
showColor(_hsl, _tempHsl);
}
else if (_isGradientMouseDown) // if change the Light
{
double offsetHeight = Gradient.ActualHeight;
double mouseY = e.GetPosition(Gradient).Y;
// calculate the new light value
double light = 1 - mouseY / offsetHeight;
light = Math.Min(1, Math.Max(0, light));
// update the picker position
LightPicker.SetValue(Canvas.TopProperty, (1 - light) * (offsetHeight - LightPicker.ActualHeight));
_tempHsl[2] = light;
showColor(_hsl, _tempHsl);
}
}
// Update the Color
void Picker_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
_isBoardMouseDown = false;
_isGradientMouseDown = false;
_tempHsl.CopyTo(_hsl, 0);
showColor(_hsl, _hsl);
}
// When Mouse Down on the Color Board
void Picker_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_isBoardMouseDown = true;
RootVisual_MouseMove(sender, e);
}
// When Mouse Down on the Gradient Box
void Gradient_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
_isGradientMouseDown = true;
RootVisual_MouseMove(sender, e);
}
/////////////////////////////////////////////////////
// Private Methods
/////////////////////////////////////////////////////
// Show the Color Differnt
private void showColor(double [] hsl1, double [] hsl2)
{
double[] rgb1 = hslToRgb(hsl1[0], hsl1[1], hsl1[2]);
double[] rgb2 = hslToRgb(hsl2[0], hsl2[1], hsl2[2]);
OldColor.Background = new SolidColorBrush(Color.FromArgb(255, (byte)rgb1[0], (byte)rgb1[1], (byte)rgb1[2]));
NewColor.Background = new SolidColorBrush(Color.FromArgb(255, (byte)rgb2[0], (byte)rgb2[1], (byte)rgb2[2]));
double[] rgb3 = hslToRgb(hsl2[0], hsl2[1], 0.5);
GradientBox.Background = new SolidColorBrush(Color.FromArgb(255, (byte)rgb3[0], (byte)rgb3[1], (byte)rgb3[2]));
}
// Convert HSL to RGB
private double [] hslToRgb(double H, double S, double L) {
double [] rgb = new double [3];
double p1 = 0;
double p2 = 0;
if (L<=0.5) {
p2 = L*(1+S);
} else {
p2 = L+S-(L*S);
}
p1 = 2*L-p2;
if (S == 0) {
rgb[0] = L;
rgb[1] = L;
rgb[2] = L;
} else {
rgb[0] = toRgb(p1, p2, H+120);
rgb[1] = toRgb(p1, p2, H);
rgb[2] = toRgb(p1, p2, H - 120);
}
rgb[0] *= 255;
rgb[1] *= 255;
rgb[2] *= 255;
return rgb;
}
// Calculate the RGB Value
private double toRgb(double q1, double q2, double hue) {
if (hue>360) {
hue = hue-360;
}
if (hue<0) {
hue = hue+360;
}
if (hue<60) {
return (q1+(q2-q1)*hue/60);
} else if (hue<180) {
return (q2);
} else if (hue<240) {
return (q1+(q2-q1)*(240-hue)/60);
} else {
return (q1);
}
}
#endregion ColorPicker
}
}
На странице где требуется вызвать диалог, например при нажатии на region
у диалогового окна есть два публичных свойства: call - текстовое поле, для указания обработчику ColorDialog_Closed какому элементу присвоить значение и Result - полученный цвет
#region ColorDialog
#region ColorDialog_Closed -- Событие закрытия окна
private void ColorDialog_Closed(object sender, EventArgs e)
{
var result = ((ChildWindow)sender).DialogResult;
if (result.HasValue)
{
//результат нажатия кнопки OK/Cancel у нас в result.Value
if (result.Value == true)
{
ColorDialog cd=(ColorDialog)sender;
if (cd.call == "colorBorder")
colorBorder.Fill = new SolidColorBrush(cd.Result);
if (cd.call == "colorFill")
colorFill.Fill = new SolidColorBrush(cd.Result);
}
}
}
#endregion ColorDialog_Closed -- Событие закрытия окна
private void colorBorder_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ColorDialog cd = new ColorDialog();
cd.Closed += new EventHandler(ColorDialog_Closed);
cd.call = "colorBorder";
cd.Show();
}
private void colorFill_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ColorDialog cd = new ColorDialog();
cd.Closed += new EventHandler(ColorDialog_Closed);
cd.call = "colorFill";
cd.Show();
}
#endregion ColorDialog