Selecting Shapes in Canvas for Windows Store App - c#

I am drawing shapes on canvas element. I want to select drawn shapes by clicking on it and want to add delete and re-size functions to it. How can i achieve that give me some tips, an example would be better if available.
Thank you

And in the code behind class we can add the events as bellow
We can do it with the help of InkManager
in the code behind class
InkManager MyInkManager = new InkManager();
string DrawingTool;
double X1, X2, Y1, Y2, StrokeThickness = 1;
Line NewLine;
Ellipse NewEllipse;
Point StartPoint, PreviousContactPoint, CurrentContactPoint;
Polyline Pencil;
Rectangle NewRectangle;
Color BorderColor = Colors.Black, FillColor;
uint PenID, TouchID;
public MainPage()
{
this.InitializeComponent();
canvas.PointerMoved += canvas_PointerMoved;
canvas.PointerReleased += canvas_PointerReleased;
canvas.PointerPressed += canvas_PointerPressed;
canvas.PointerExited += canvas_PointerExited;
for (int i = 1; i < 21; i++)
{
ComboBoxItem Items = new ComboBoxItem();
Items.Content = i;
cbStrokeThickness.Items.Add(Items);
}
cbStrokeThickness.SelectedIndex = 0;
//var t = typeof(Colors);
//var ti = t.GetTypeInfo();
//var dp = ti.DeclaredProperties;
var colors = typeof(Colors).GetTypeInfo().DeclaredProperties;
foreach (var item in colors)
{
cbBorderColor.Items.Add(item);
cbFillColor.Items.Add(item);
}
}
then we need to define the canvas pointer events.here i am giving one example lets say pointer move event
void canvas_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if (DrawingTool != "Eraser")
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.Cross, 1);
else
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.UniversalNo, 1);
switch (DrawingTool)
{
case "Pencil":
{
/* Old Code
if (e.GetCurrentPoint(canvas).Properties.IsLeftButtonPressed == true)
{
if (StartPoint != e.GetCurrentPoint(canvas).Position)
{
Pencil.Points.Add(e.GetCurrentPoint(canvas).Position);
}
}
*/
if (e.Pointer.PointerId == PenID || e.Pointer.PointerId == TouchID)
{
// Distance() is an application-defined function that tests
// whether the pointer has moved far enough to justify
// drawing a new line.
CurrentContactPoint = e.GetCurrentPoint(canvas).Position;
X1 = PreviousContactPoint.X;
Y1 = PreviousContactPoint.Y;
X2 = CurrentContactPoint.X;
Y2 = CurrentContactPoint.Y;
if (Distance(X1, Y1, X2, Y2) > 2.0)
{
Line line = new Line()
{
X1 = X1,
Y1 = Y1,
X2 = X2,
Y2 = Y2,
StrokeThickness = StrokeThickness,
Stroke = new SolidColorBrush(BorderColor)
};
PreviousContactPoint = CurrentContactPoint;
canvas.Children.Add(line);
MyInkManager.ProcessPointerUpdate(e.GetCurrentPoint(canvas));
}
}
}
break;
case "Line":
{
if (e.GetCurrentPoint(canvas).Properties.IsLeftButtonPressed == true)
{
NewLine.X2 = e.GetCurrentPoint(canvas).Position.X;
NewLine.Y2 = e.GetCurrentPoint(canvas).Position.Y;
}
}
break;
case "Rectagle":
{
if (e.GetCurrentPoint(canvas).Properties.IsLeftButtonPressed == true)
{
X2 = e.GetCurrentPoint(canvas).Position.X;
Y2 = e.GetCurrentPoint(canvas).Position.Y;
if ((X2 - X1) > 0 && (Y2 - Y1) > 0)
NewRectangle.Margin = new Thickness(X1, Y1, X2, Y2);
else if ((X2 - X1) < 0)
NewRectangle.Margin = new Thickness(X2, Y1, X1, Y2);
else if ((Y2 - Y1) < 0)
NewRectangle.Margin = new Thickness(X1, Y2, X2, Y1);
else if ((X2 - X1) < 0 && (Y2 - Y1) < 0)
NewRectangle.Margin = new Thickness(X2, Y1, X1, Y2);
NewRectangle.Width = Math.Abs(X2 - X1);
NewRectangle.Height = Math.Abs(Y2 - Y1);
}
}
break;
case "Ellipse":
{
if (e.GetCurrentPoint(canvas).Properties.IsLeftButtonPressed == true)
{
X2 = e.GetCurrentPoint(canvas).Position.X;
Y2 = e.GetCurrentPoint(canvas).Position.Y;
if ((X2 - X1) > 0 && (Y2 - Y1) > 0)
NewEllipse.Margin = new Thickness(X1, Y1, X2, Y2);
else if ((X2 - X1) < 0)
NewEllipse.Margin = new Thickness(X2, Y1, X1, Y2);
else if ((Y2 - Y1) < 0)
NewEllipse.Margin = new Thickness(X1, Y2, X2, Y1);
else if ((X2 - X1) < 0 && (Y2 - Y1) < 0)
NewEllipse.Margin = new Thickness(X2, Y1, X1, Y2);
NewEllipse.Width = Math.Abs(X2 - X1);
NewEllipse.Height = Math.Abs(Y2 - Y1);
}
}
break;
case "Eraser":
{
if (e.GetCurrentPoint(canvas).Properties.IsLeftButtonPressed == true)
{
if (StartPoint != e.GetCurrentPoint(canvas).Position)
{
Window.Current.CoreWindow.PointerCursor = new CoreCursor(CoreCursorType.UniversalNo, 1);
Pencil.Points.Add(e.GetCurrentPoint(canvas).Position);
}
}
}
break;
default:
break;
}
}
Then lets say we need to define the drawing tools click event as bellow
private void btnPencil_Click(object sender, RoutedEventArgs e)
{
DrawingTool = "Pencil";
}
private void btnLine_Click(object sender, RoutedEventArgs e)
{
DrawingTool = "Line";
}
private void btnEllipse_Click(object sender, RoutedEventArgs e)
{
DrawingTool = "Ellipse";
}
private void btnRectagle_Click(object sender, RoutedEventArgs e)
{
DrawingTool = "Rectagle";
}
private void btnEraser_Click(object sender, RoutedEventArgs e)
{
DrawingTool = "Eraser";
}
private void btnClearScreen_Click(object sender, RoutedEventArgs e)
{
//MyInkManager.Mode = InkManipulationMode.Erasing;
//for (int i = 0; i < MyInkManager.GetStrokes().Count; i++)
// MyInkManager.GetStrokes().ElementAt(i).Selected = true;
//MyInkManager.DeleteSelected();
txtRecognizedText.Text = string.Empty;
canvas.Children.Clear();
}
Here i am giving you example of some of the event.
Hope this will help you in some extent

This may help you
for the Style of the Button you can add the style in the Page Resource as bellow
<Page.Resources>
<Style x:Key="PaintButton" TargetType="Button">
<Setter Property="FontFamily" Value="Segoe UI Symbol"/>
<Setter Property="FontWeight" Value="Normal"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="Width" Value="auto"/>
<Setter Property="Height" Value="50"/>
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Grid.Row" Value="0"/>
</Style>
</Page.Resources>
then for adding the drawn shape list we can add it to the Grid
<StackPanel Orientation="Horizontal" Margin="80,0,-43,0" Grid.Row="1">
<Button x:Name="btnLine" Click="btnLine_Click" Content="╱" Style="{StaticResource PaintButton}" ToolTipService.ToolTip="Line"/>
<Button x:Name="btnEllipse" Click="btnEllipse_Click" Style="{StaticResource PaintButton}" Content="◯" ToolTipService.ToolTip="Ellipse"/>
<Button x:Name="btnPencil" Click="btnPencil_Click" Style="{StaticResource PaintButton}" Content="✎" ToolTipService.ToolTip="Pencil"/>
<Button x:Name="btnRectagle" Click="btnRectagle_Click" Style="{StaticResource PaintButton}" Content="▭" ToolTipService.ToolTip="Rectangle"/>
<Button x:Name="btnEraser" Click="btnEraser_Click" Style="{StaticResource PaintButton}" Content="∅" ToolTipService.ToolTip="Eraser"/>
<Button x:Name="btnClearScreen" Click="btnClearScreen_Click" Style="{StaticResource PaintButton}" Content="❌" ToolTipService.ToolTip="Clear Screen"/>
<Button x:Name="btnRecognize" Click="btnRecognize_Click" Style="{StaticResource PaintButton}" Content="R" ToolTipService.ToolTip="Handwriting Recognition"/>
<TextBlock x:Name="tbBorderColor" Text="Border Colors : " VerticalAlignment="Center" FontSize="15" TextWrapping="Wrap" Padding="15,0,0,0" Margin="0"/>
<ComboBox x:Name="cbBorderColor" Width="200" Height="40" ItemsSource="{Binding Colors}" SelectedItem="{Binding SelectedColorName, Mode=TwoWay}" SelectionChanged="cbBorderColor_SelectionChanged" Padding="8,0" Margin="10,0,0,0">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Width="35" Height="20" Fill="{Binding Name}" Margin="5,0"/>
<TextBlock Grid.Column="1" Margin="10,0,0,0" Text="{Binding Name}" Foreground="Black"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock x:Name="tbFillColor" Text="Fill Colors : " VerticalAlignment="Center" FontSize="15" Padding="15,0,0,0"/>
<ComboBox x:Name="cbFillColor" Width="200" Height="40" ItemsSource="{Binding Colors}" SelectedItem="{Binding SelectedColorName, Mode=TwoWay}" SelectionChanged="cbFillColor_SelectionChanged" Margin="10,0,0,0">
<ComboBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Rectangle Width="35" Height="20" Fill="{Binding Name}" Margin="5,0"/>
<TextBlock Grid.Column="1" Margin="10,0,0,0" Text="{Binding Name}" Foreground="Black"/>
</Grid>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!--<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="tbBorderColor" Text="Border Colors : " Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" FontSize="15" TextWrapping="Wrap" Grid.RowSpan="3" Padding="15,0,0,0"/>
<Button x:Name="btnRed" Background="Red" Height="20" Width="20" Click="btnRed_Click" Grid.Row="0" Grid.Column="1" BorderThickness="0"/>
<Button x:Name="btnGreen" Background="Green" Height="20" Width="20" Click="btnGreen_Click" Grid.Row="0" Grid.Column="2" BorderThickness="0"/>
<Button x:Name="btnBlue" Background="Blue" Height="20" Width="20" Click="btnBlue_Click" Grid.Row="0" Grid.Column="3" BorderThickness="0"/>
<Button x:Name="btnBlack" Background="Black" Height="20" Width="20" Click="btnBlack_Click" Grid.Row="1" Grid.Column="1" BorderThickness="0"/>
<Button x:Name="btnYellow" Background="Yellow" Height="20" Width="20" Click="btnYellow_Click" Grid.Row="1" Grid.Column="2" BorderThickness="0"/>
<Button x:Name="btnMagenta" Background="Magenta" Height="20" Width="20" Click="btnMagenta_Click" Grid.Row="1" Grid.Column="3" BorderThickness="0"/>
<Button x:Name="btnCyan" Background="Cyan" Height="20" Width="20" Click="btnCyan_Click" Grid.Row="2" Grid.Column="1" BorderThickness="0"/>
<Button x:Name="btnWhite" Background="White" Height="20" Width="20" Click="btnWhite_Click" Grid.Row="2" Grid.Column="2" BorderThickness="0"/>
<Button x:Name="btnPink" Background="Pink" Height="20" Width="20" Click="btnPink_Click" Grid.Row="2" Grid.Column="3" BorderThickness="0"/>
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="20"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="tbFillColor" Text="Fill Colors : " Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Grid.RowSpan="3" FontSize="15" TextWrapping="Wrap" Padding="15,0,0,0"/>
<Button x:Name="btnFillRed" Background="Red" Height="20" Width="20" Click="btnFillRed_Click" Grid.Row="0" Grid.Column="1" BorderThickness="0"/>
<Button x:Name="btnFillGreen" Background="Green" Height="20" Width="20" Click="btnFillGreen_Click" Grid.Row="0" Grid.Column="2" BorderThickness="0"/>
<Button x:Name="btnFillBlue" Background="Blue" Height="20" Width="20" Click="btnFillBlue_Click" Grid.Row="0" Grid.Column="3" BorderThickness="0"/>
<Button x:Name="btnFillBlack" Background="Black" Height="20" Width="20" Click="btnFillBlack_Click" Grid.Row="1" Grid.Column="1" BorderThickness="0"/>
<Button x:Name="btnFillYellow" Background="Yellow" Height="20" Width="20" Click="btnFillYellow_Click" Grid.Row="1" Grid.Column="2" BorderThickness="0"/>
<Button x:Name="btnFillMagenta" Background="Magenta" Height="20" Width="20" Click="btnFillMagenta_Click" Grid.Row="1" Grid.Column="3" BorderThickness="0"/>
<Button x:Name="btnFillCyan" Background="Cyan" Height="20" Width="20" Click="btnFillCyan_Click" Grid.Row="2" Grid.Column="1" BorderThickness="0"/>
<Button x:Name="btnFillWhite" Background="White" Height="20" Width="20" Click="btnFillWhite_Click" Grid.Row="2" Grid.Column="2" BorderThickness="0"/>
<Button x:Name="btnFillPink" Background="Pink" Height="20" Width="20" Click="btnFillPink_Click" Grid.Row="2" Grid.Column="3" BorderThickness="0"/>
</Grid>-->
<TextBlock x:Name="tbStrokeThickness" Text="Stroke Thickness :" FontSize="15" TextWrapping="Wrap" Padding="15,0,0,0" MaxWidth="90" VerticalAlignment="Center"/>
<ComboBox x:Name="cbStrokeThickness" SelectionChanged="cbStrokeThickness_SelectionChanged" Margin="10,0,0,0" Height="30"/>
</StackPanel>
then add the canvas
<Canvas Name="canvas" Background="Wheat" Grid.Row="3" Grid.RowSpan="1" Margin="0,20,0,0">
</Canvas>
This will for the xaml

Related

UWP: Adjusting InkCanvas size when writing/drawing

I'm learning how to develop UWP apps and I'm using Microsoft's documentation as tutorials/research.
I want to have an InkCanvas design similar to OneNote where the InkCanvas height and width can expand (as you're writing/drawing and reach the end of the window size) and can shrink (when you erase ink strokes and the extra size can decrease based on the position of the ink strokes until you get back to the original size).
I'm able to increase the InkCanvas width and height, but can't decrease when erasing ink strokes.
Here is a MainPage.xaml code:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Heading"
FontSize="36"
FontWeight="Bold"
Margin="10"
Grid.Column="0"
Grid.Row="0"/>
<Grid BorderBrush="Red"
BorderThickness="2"
Margin="10"
Grid.Column="0"
Grid.Row="1">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
HorizontalScrollMode="Enabled"
VerticalScrollBarVisibility="Auto"
VerticalScrollMode="Enabled" >
<Grid BorderBrush="Blue"
BorderThickness="2"
Margin="1">
<InkCanvas Name="inkCanvas"/>
</Grid>
</ScrollViewer>
</Grid>
And the MainPage.cs code:
public MainPage()
{
this.InitializeComponent();
nkCanvas.InkPresenter.StrokeInput.StrokeEnded += adjustInkCanvasSize;
}
private async void adjustInkCanvasSize(InkStrokeInput sender, PointerEventArgs args)
{
await Task.Delay(100);
var XBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Bottom;
if (XBound > inkCanvas.ActualHeight - 200)
inkCanvas.Height = XBound + 200;
var YBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Right;
if (YBound > inkCanvas.ActualWidth - 200)
inkCanvas.Width = YBound + 200;
}
The c# code also came from another stackoverflow solution, but not able to figure out the "decrease" part.
Any help would be much appreciated. Thanks
If you want the InkCanvas control to shrink when you erase ink strokes and the extra size can decrease based on the position of the ink strokes until the original size, you need to add the InkPresenter.StrokesErased event to manage the size of the InkCanvas control. For example:
Here is a MainPage.xaml code( To facilitate testing, I added the mouse support):
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Heading"
FontSize="36"
FontWeight="Bold"
Margin="10"
Grid.Column="0"
Grid.Row="0"/>
<Grid BorderBrush="Red"
BorderThickness="2"
Margin="10"
Grid.Column="0"
Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<InkToolbar x:Name="inkToolbar" VerticalAlignment="Top" Margin="10,0,10,0"
TargetInkCanvas="{x:Bind inkCanvas}" Grid.Row="0"/>
<ScrollViewer HorizontalScrollBarVisibility="Auto"
HorizontalScrollMode="Enabled" Grid.Row="1"
VerticalScrollBarVisibility="Auto"
VerticalScrollMode="Enabled" >
<Grid BorderBrush="Blue"
BorderThickness="2"
Margin="1">
<InkCanvas Name="inkCanvas" />
</Grid>
</ScrollViewer>
</Grid>
</Grid>
And the MainPage.cs code:
public sealed partial class MainPage : Page
{
private double originalX; //The original size
private double originalY;
private double maxX=0.0;
private double maxY=0.0;
private bool flag = true;
public MainPage()
{
this.InitializeComponent();
inkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Touch |
CoreInputDeviceTypes.Pen;
inkCanvas.InkPresenter.StrokeInput.StrokeEnded += adjustInkCanvasSize;
inkCanvas.InkPresenter.StrokesErased += InkPresenter_StrokesErased;
}
private async void InkPresenter_StrokesErased(InkPresenter sender, InkStrokesErasedEventArgs args)
{
await Task.Delay(100);
//The coordinate of the lower right corner of the erased ink stoke
var erasedInkX= args.Strokes.ElementAt(0).BoundingRect.Bottom;
var erasedInkY = args.Strokes.ElementAt(0).BoundingRect.Right;
var XBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Bottom;
if (erasedInkX >=maxX&&XBound < inkCanvas.ActualHeight + 100)
{
if (XBound - 100 > originalX)
inkCanvas.Height = XBound - 100;
else
inkCanvas.Height = originalX; //The size of InkCanvas shrinks to the original size.
maxX = inkCanvas.Height;
}
var YBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Right;
if (erasedInkY>=maxY&&YBound < inkCanvas.ActualWidth + 100)
{
if (YBound - 100 > originalY)
{
inkCanvas.Width = YBound - 100;
}
else
inkCanvas.Width = originalY;
maxY = inkCanvas.Width;
}
}
private async void adjustInkCanvasSize(InkStrokeInput sender, PointerEventArgs args)
{
await Task.Delay(100);
if(flag)
{
flag = false;
originalX = inkCanvas.ActualHeight; //Get the original size
originalY = inkCanvas.ActualWidth;
}
var XBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Bottom;
if (XBound > maxX)
maxX = XBound; //maxX and maxY always hold the maximum size of StrokeContainer
if (XBound > inkCanvas.ActualHeight - 200)
inkCanvas.Height = XBound + 200;
var YBound = inkCanvas.InkPresenter.StrokeContainer.BoundingRect.Right;
if (YBound > maxY)
maxY = YBound;
if (YBound > inkCanvas.ActualWidth - 200)
inkCanvas.Width = YBound + 200;
}
}

2nd Legend canvas not showing in wpf chart

I've been struggling with this for some time now. The problem relates to adding a second legend canvas in a wpf chart. I'm referencing Jack Yu's book Practical WPF Charts and Graphics LineChartWithLegend.xaml file. In the xaml file, I added the new legend canvas named "legendCanvas2". I've changed the code behind to add a second instance of the legend in the AddChart() method. The problem is the second legend does not show inside chartCanvas. I suspect this issue has to do with multiple canvas containers inside chartCanvas but not sure. Any help with alternative ways I can display two legends inside chartCanvas would be appreciated.
XAML
<Window x:Class="LineCharts.LineChartWithLegend"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Line Chart with Legend" Height="400" Width="500">
<Grid Name="grid1" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Name="column1" Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Name="row1" Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Margin="2" x:Name="tbTitle" Grid.Column="1" Grid.Row="0"
RenderTransformOrigin="0.5,0.5" FontSize="14" FontWeight="Bold"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TextAlignment="Center"
Text="Title"/>
<TextBlock Margin="2" x:Name="tbXLabel" Grid.Column="1" Grid.Row="2"
RenderTransformOrigin="0.5,0.5" TextAlignment="Center"
Text="X Axis"/>
<TextBlock Margin="2" Name="tbYLabel" Grid.Column="0" Grid.Row="1"
RenderTransformOrigin="0.5,0.5" TextAlignment="Center"
Text="Y Axis">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
<Grid Margin="0" x:Name ="chartGrid" Grid.Column="1" Grid.Row="1"
ClipToBounds="True" Background="Transparent" SizeChanged="chartGrid_SizeChanged" />
<Canvas Margin="2" Name="textCanvas" ClipToBounds="True" Grid.Column="1" Grid.Row="1">
<Canvas Name="chartCanvas" ClipToBounds="True">
<Canvas Name="legendCanvas" Background="Transparent" />
<Canvas Name="legendCanvas2" Background="Transparent" />
</Canvas>
</Canvas>
</Grid>
</Window>
Code-Behind
private void AddChart()
{
cs = new ChartStyleGridlines();
lg = new Legend();
lg2 = new Legend();
dc = new DataCollection();
ds = new DataSeries();
cs.ChartCanvas = chartCanvas;
cs.TextCanvas = textCanvas;
cs.Title = "Sine and Cosine Chart";
cs.Xmin = 0;
cs.Xmax = 7;
cs.Ymin = -1.5;
cs.Ymax = 1.5;
cs.YTick = 0.5;
cs.GridlinePattern = ChartStyleGridlines.GridlinePatternEnum.Dot;
cs.GridlineColor = Brushes.Black;
cs.AddChartStyle(tbTitle, tbXLabel, tbYLabel);
// Draw Sine curve:
ds.LineColor = Brushes.Blue;
ds.LineThickness = 1;
ds.SeriesName = "Sine";
for (int i = 0; i < 70; i++)
{
double x = i / 5.0;
double y = Math.Sin(x);
ds.LineSeries.Points.Add(new Point(x, y));
}
dc.DataList.Add(ds);
// Draw cosine curve:
ds = new DataSeries();
ds.LineColor = Brushes.Red;
ds.SeriesName = "Cosine";
ds.LinePattern = DataSeries.LinePatternEnum.DashDot;
ds.LineThickness = 2;
for (int i = 0; i < 70; i++)
{
double x = i / 5.0;
double y = Math.Cos(x);
ds.LineSeries.Points.Add(new Point(x, y));
}
dc.DataList.Add(ds);
// Draw sine^2 curve:
ds = new DataSeries();
ds.LineColor = Brushes.DarkGreen;
ds.SeriesName = "Sine^2";
ds.LinePattern = DataSeries.LinePatternEnum.Dot;
ds.LineThickness = 2;
for (int i = 0; i < 70; i++)
{
double x = i / 5.0;
double y = Math.Sin(x) * Math.Sin(x);
ds.LineSeries.Points.Add(new Point(x, y));
}
dc.DataList.Add(ds);
dc.AddLines(cs);
lg.LegendCanvas = legendCanvas;
lg.IsLegend = true;
lg.IsBorder = true;
lg.LegendPosition = Legend.LegendPositionEnum.NorthWest;
lg.AddLegend(cs.ChartCanvas, dc);
lg2 = new Legend();
lg2.LegendCanvas = legendCanvas2;
lg2.IsLegend = true;
lg2.IsBorder = true;
lg2.LegendPosition = Legend.LegendPositionEnum.NorthEast;
lg2.AddLegend(cs.ChartCanvas, dc);
}
private void chartGrid_SizeChanged(object sender, SizeChangedEventArgs e)
{
textCanvas.Width = chartGrid.ActualWidth;
textCanvas.Height = chartGrid.ActualHeight;
legendCanvas.Children.Clear();
legendCanvas2.Children.Clear();
chartCanvas.Children.RemoveRange(2, chartCanvas.Children.Count - 1); // changed index from 1 to 2
textCanvas.Children.RemoveRange(1, textCanvas.Children.Count - 1);
AddChart();
}

EllipseGeometry Shrink & Fade Without Exceeding Canvas Bounds in C# WPF

How to make animation stay within the canvas at bigger sizes when the user clicks around the edge of the canvas? Currently, if sizes are too big and if user clicks near the edge of the canvas, the ellipse will grow outside of the canvas to cover the buttons. I need the animation to stay within the canvas to make it look like a slice of pizza essentially.
Should look like this:
Size 50 where user clicks near top left of canvas
Currently looks like this:
Size 50 where user clicks near top left of canvas
Xaml:
<Window.Resources>
<Storyboard x:Key="anim">
<DoubleAnimation
Storyboard.TargetName="myCircle"
Storyboard.TargetProperty="RadiusX"
AutoReverse="True"/>
<DoubleAnimation
Storyboard.TargetName="myCircle"
Storyboard.TargetProperty="RadiusY"
AutoReverse="True"/>
<DoubleAnimation
Storyboard.TargetName="path"
Storyboard.TargetProperty="Opacity"
AutoReverse="True"/>
</Storyboard>
</Window.Resources>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="23"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Margin="0,0,0,1">
<Menu DockPanel.Dock="Top" Height="23">
<MenuItem Header="Main" RenderTransformOrigin="-1.896,0.643" HorizontalAlignment="Left" Width="39" Height="23">
<MenuItem Header="Exit, Esc" Click="MenuItem_Click_Exit"/>
</MenuItem>
</Menu>
</DockPanel>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Name="pane">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="0" Name="pane2">
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="35"/>
<RowDefinition Height="35"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<Label Content="Size" Grid.Row="0" Grid.Column="0" Height="25" VerticalAlignment="Stretch"/>
<Label Content="Fill Color" Grid.Row="1" Grid.Column="0" Height="25" VerticalAlignment="Stretch"/>
<Label Content="Stroke Thickness" Grid.Row="2" Grid.Column="0" Height="25" VerticalAlignment="Stretch"/>
<Label Content="Stroke Color" Grid.Row="3" Grid.Column="0" VerticalAlignment="Top" Height="25"/>
<Slider x:Name="Slider_Size" Grid.Row="0" Grid.Column="1" Height="20" Width="45"
Minimum="5" Maximum="50"
AutoToolTipPlacement="BottomRight"
TickFrequency="1"
IsSnapToTickEnabled="True"
PreviewMouseUp="Slider_Size_PreviewMouseUp"/>
<Label Name="tempSize" Content="{Binding Path=Value, ElementName=Slider_Size}" Margin="0,25,0,131" Grid.Row="3" Visibility="Hidden"/>
<ComboBox Name="ComboBox_FillColor" Grid.Row="1" Grid.Column="1" Height="20" Width="45" SelectionChanged="ComboBox_FillColor_Selected"/>
<TextBox Name="textBox" Grid.Row="2" Grid.Column="1" Height="20" Width="45" TextChanged="textBox_TextChanged"/>
<ComboBox Name="ComboBox_StrokeColor" Grid.Row="3" Grid.Column="1" VerticalAlignment="Top" Height="20" Width="45" SelectionChanged="ComboBox_StrokeColor_Selected"/>
</Grid>
<Border Name ="border" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Black" Grid.Column="1" BorderThickness="2">
<Canvas Name="canvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MouseDown="Canvas_MouseDown">
<Path x:Name="path">
<Path.Data>
<EllipseGeometry x:Name="myCircle"/>
</Path.Data>
</Path>
<Canvas.Background>
<SolidColorBrush Color="White" Opacity="0"/>
</Canvas.Background>
</Canvas>
</Border>
</Grid>
</Grid>
C#:
public partial class MainWindow : Window
{
private int size;
private SolidColorBrush fillColor;
private SolidColorBrush strokeColor;
private List<SolidColorBrush> colors;
private int fillIndex;
private int strokeIndex;
private int strokeThickness = 1;
private int fillColorDefault;
private int strokeColorDefault;
private Point? _start = null;
public MainWindow()
{
InitializeComponent();
addColors();
textBox.Text = strokeThickness.ToString();
parse();
}
private void MenuItem_Click_Exit(object sender, RoutedEventArgs e) { Environment.Exit(1); }
private void Window_KeyUp_ESC(object sender, KeyEventArgs e)
{
if (Key.Escape == e.Key)
MenuItem_Click_Exit(sender, e);
}
private void addColors()
{
colors = typeof(Brushes).GetProperties().Select(p => p.GetValue(null, null) as SolidColorBrush).ToList();
int count = 0;
foreach (SolidColorBrush color in colors)
{
ComboBox_FillColor.Items.Add(new Rectangle() { Height = 12, Width = 17.5, Fill = color });
ComboBox_StrokeColor.Items.Add(new Rectangle() { Height = 12, Width = 17.5, Fill = color });
if (color.Color == Colors.Red)
{
fillIndex = count;
fillColor = colors[fillIndex];
ComboBox_FillColor.SelectedIndex = count;
fillColorDefault = count;
}
if (color.Color == Colors.Black)
{
strokeIndex = count;
strokeColor = colors[strokeIndex];
ComboBox_StrokeColor.SelectedIndex = count;
strokeColorDefault = count;
}
count++;
}
}
private void ComboBox_FillColor_Selected(object sender, RoutedEventArgs e) { fillIndex = ComboBox_FillColor.SelectedIndex; fillColor = colors[fillIndex]; }
private void ComboBox_StrokeColor_Selected(object sender, RoutedEventArgs e) { strokeIndex = ComboBox_StrokeColor.SelectedIndex; strokeColor = colors[strokeIndex]; }
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
path.Stroke = strokeColor;
path.StrokeThickness = strokeThickness;
path.Fill = fillColor;
path.HorizontalAlignment = HorizontalAlignment.Stretch;
path.VerticalAlignment = VerticalAlignment.Stretch;
path.Stretch = Stretch.None;
path.SetValue(Grid.ColumnProperty, 1);
_start = Mouse.GetPosition((UIElement)sender);
myCircle.Center = (Point)_start;
var sb = FindResource("anim") as Storyboard;
var x = sb.Children.First() as DoubleAnimation;
x.To = 2 * size;
x.Duration = new Duration(TimeSpan.FromSeconds(0.5));
var y = sb.Children.ElementAt(1) as DoubleAnimation;
y.To = 2 * size;
y.Duration = new Duration(TimeSpan.FromSeconds(0.5));
var z = sb.Children.Last() as DoubleAnimation;
z.From = 0.0;
z.To = 1.0;
z.Duration = new Duration(TimeSpan.FromSeconds(0.5));
sb.Begin(path);
}
private void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
//regex where any string of chars besides numbers
Regex pattern = new Regex(#"^([^0-9]*)$", RegexOptions.Compiled);
Match result = pattern.Match(textBox.Text);
if (textBox.Text.ToString() == string.Empty)
return;
else if (result.Success)
{
MessageBox.Show("Invalid character entered. Integer numbers only. Stroke Thickness will be reseted to a default of 1.");
strokeThickness = 1;
textBox.Text = strokeThickness.ToString();
textBox.SelectAll();
}
else
{
int x;
if (int.TryParse(textBox.Text, out x))
strokeThickness = int.Parse(textBox.Text);
}
}
private void Slider_Size_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
parse();
}
private void parse()
{
int x;
if (int.TryParse(tempSize.Content.ToString(), out x))
size = x;
}
}
}
So you don't need the ellipse to stay within the Canvas, but you want to clip away the parts leaving it, right? Just set ClipToBounds (of Canvas) to true (can be done in Xaml).

Grid or border not allowing drop

I have to do a drag and drop application listView to code-generated grid.
So I have done a test program and that works
here is the xaml
<Grid Margin="0,0,-61.6,0.4">
<ListView x:Name="lwOne" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown" Background="Bisque" Margin="16,65,340.2,22">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" Width="250" VerticalAlignment="Top"></WrapPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<Grid Name="grdMain" Drop="Grid_Drop" Background="AliceBlue" AllowDrop="True" Margin="380,65,81.2,62"/>
Now I have to migrate all this to my real application Which looks like that
So from how the cursor looks like i can see that the drag and drop is not allowed on the grid but it is on the tiny border of each cell.
So the problem is not doing d&d but ALLOWING to it
here is the xaml. The source listView is lvAllowedPPtab2, the destination grid is grdPalletTab2
<TabItem Name="tabItem2" HorizontalAlignment="Center" Height="80" MouseLeftButtonUp="TabItem_MouseLeftButtonUp" FontSize="{StaticResource TOOLTIP_FONTSIZE}" IsSelected="false" >
<TabItem.Header>
<StackPanel>
<TextBlock Text="" FontSize="{StaticResource TAB_FONTSIZE}"/>
<TextBlock Name="tbTab2" Visibility="Hidden" FontSize="{StaticResource BUTTON_FONTSIZE}" />
</StackPanel>
</TabItem.Header>
<TabItem.Background>
<ImageBrush/>
</TabItem.Background>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border x:Name="Border1Tab2" BorderBrush="Gainsboro" BorderThickness="5" Width="200" Margin="10,10,10,10" >
<StackPanel Margin="-1.8,-0.8,2.2,1.4">
<ListBox x:Name="lbxPalletsTab2" Background="{x:Null}" BorderBrush="{x:Null}" Height="600" SelectionChanged="ListBox_SelectionChanged" Margin="12,10.2,8.4,10.4" />
</StackPanel>
</Border>
<Border x:Name="Border2Tab2" BorderBrush="Gainsboro" MinWidth="150" BorderThickness="5" Grid.Column="1" Margin="10,10,10,10">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300px"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid HorizontalAlignment="Stretch" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="50px"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="tbkPPtab2" Grid.Row="0" FontSize="22" Background="{x:Null}" FontWeight="Black" Text="---" HorizontalAlignment="Center" VerticalAlignment="Bottom"></TextBlock>
<ListView x:Name="lvAllowedPPtab2" Grid.Row="1" FontSize="12" Background="{x:Null}" BorderBrush="Gainsboro" BorderThickness="5" Margin="10" VerticalAlignment="Stretch" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown">
<ListView.ItemsPanel >
<ItemsPanelTemplate >
<WrapPanel Orientation="Horizontal" Width="250" Background="{x:Null}" VerticalAlignment="Top"></WrapPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
<Border Grid.Column="1" BorderBrush="Gainsboro" BorderThickness="5" Margin="10,60,10,10">
<Grid Name="grdPalletTab2" AllowDrop="True" Drop="Grid_Drop"/>
</Border>
</Grid>
</Border>
</Grid>
</TabItem>
the grid is formed through
PalletWindow.PalletWindow.SetPalletGrid(numRows, numColumns,ref grdPalletTab2);
whose code is:
public static bool SetPalletGrid(int numRows, int numColumns, ref Grid grd)
{
try
{
grd.Children.Clear();
grd.RowDefinitions.Clear();
grd.ColumnDefinitions.Clear();
grd.AllowDrop = true;
for (int row = 0; row < numRows; row++)
{
var rd = new RowDefinition();
rd.AllowDrop = true;
rd.Height = new GridLength(1.0, GridUnitType.Star);
grd.RowDefinitions.Add(rd);
}
for (int column = 0; column < numColumns; column++)
{
var cd = new ColumnDefinition();
cd.AllowDrop = true;
cd.Width = new GridLength(1.0, GridUnitType.Star);
grd.ColumnDefinitions.Add(cd);
}
for (int row = 0; row < numRows; row++)
{
for (int column = 0; column < numColumns; column++)
{
var borderImage = new Border();
borderImage.AllowDrop = true;
borderImage.BorderThickness = new Thickness(2);
borderImage.BorderBrush = new SolidColorBrush(Colors.Black);
borderImage.Name = "BRD_" + row + "_" + column;
borderImage.Effect = new DropShadowEffect
{
Color = new Color { R = 255, G = 255, B = 255 },
Direction = 320,
ShadowDepth = 5,
Opacity = 0.95
};
Grid.SetRow(borderImage, row);
Grid.SetColumn(borderImage, column);
grd.Children.Add(borderImage);
}
}
return true;
}
catch// (Exception exc)
{
return false;
}
}
thanks for any help
Patrick
To make d&d work you have to set the background of the target element (don't know why). In your case set borderImage = new SolidColorBrush(Colors.Transparent);

How to find element in visual tree in wp7?

I need to find element in visual tree. For example I have a grid and I need to set my own text in tbox:WatermarkTextBox when ExpanderView expands.
xaml
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="280"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="0" >
<Border/>
</Grid>
<Grid Grid.Row="0" />
<Grid Grid.Row="0" Grid.Column="2" />
<toolkit:ExpanderView Expanded="setText" Collapsed="hideAppBar">
<Image Height="100" Margin="-53,0,0,0"/>
</toolkit:ExpanderView>
<toolkit:ExpanderView x:Name="expText" IsExpanded="False" Tag="{Binding}" Grid.Row="1" Grid.Column="1" VerticalContentAlignment="Stretch" Grid.ColumnSpan="2" Background="White" Foreground="Black" BorderBrush="White">
<tbox:WatermarkTextBox TextChanged="DisableOrEnable" TextWrapping="Wrap" AcceptsReturn="True" WatermarkText="Введите комментарий" BorderThickness="0" InputScope="Chat" Margin="-51,0,0,0" Padding="0" Background="White" BorderBrush="White"/>
</toolkit:ExpanderView>
...many elements
</Grid>
c#
public string message="my message";
private void setText(object sender, RoutedEventArgs e)
{
setMessage(((sender as ExpanderView).Parent as Grid));
}
Function that recursively searching through visual tree and set value to the element that you need:
public void setMessage(DependencyObject parent)
{
if (parent == null)
{
return;
}
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(parent, i);
var frameworkElement = child as FrameworkElement;
if (frameworkElement != null && frameworkElement is WatermarkTextBox/*Type of element that you need*/)
{
(frameworkElement as WatermarkTextBox).Text = message;/*Value that you need*/
break;
}else
if (frameworkElement != null)
{
int CountInChildren = VisualTreeHelper.GetChildrenCount(frameworkElement);
for (int z = 0; z < CountInChildren; z++)
{
DependencyObject child1 = VisualTreeHelper.GetChild(frameworkElement, z);
setMessage(frameworkElement);
}
}
}
}

Categories

Resources