Crop Image using Canvas Rectangle - c#

Cropping the image is not working properly. Where I'm wrong?
My Xaml :
<Grid x:Name="Gridimage1">
<Image Name="image1" Grid.Column="0" Height="317" HorizontalAlignment="Left" Margin="20,67,0,0" Stretch="Fill" VerticalAlignment="Top" Width="331"></Image>
<Canvas x:Name="BackPanel">
<Rectangle x:Name="selectionRectangle" Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" />
</Canvas>
</Grid>
<Button Content=">>" Height="23" HorizontalAlignment="Left" Margin="357,201,0,0" Name="Go" VerticalAlignment="Top" Width="41" Click="Go_Click" FontWeight="Bold" Visibility="Hidden" />
<Image Grid.Column="1" Height="317" HorizontalAlignment="Left" Margin="408,67,0,0" Name="image2" Stretch="Fill" VerticalAlignment="Top" Width="331" />
C# :
private bool isDragging = false;
private Point anchorPoint = new Point();
public MainWindow()
{
InitializeComponent();
Gridimage1.MouseLeftButtonDown += new MouseButtonEventHandler(image1_MouseLeftButtonDown);
Gridimage1.MouseMove += new MouseEventHandler(image1_MouseMove);
Gridimage1.MouseLeftButtonUp += new MouseButtonEventHandler(image1_MouseLeftButtonUp);
Go.IsEnabled = false;
image2.Source = null;
}
private void Go_Click(object sender, RoutedEventArgs e)
{
if (image1.Source != null)
{
Rect rect1 = new Rect(Canvas.GetLeft(selectionRectangle), Canvas.GetTop(selectionRectangle), selectionRectangle.Width, selectionRectangle.Height);
System.Windows.Int32Rect rcFrom = new System.Windows.Int32Rect();
rcFrom.X = (int)((rect1.X) * (image1.Source.Width) /(image1.Width));
rcFrom.Y = (int)((rect1.Y) *(image1.Source.Height) / (image1.Height));
rcFrom.Width = (int)((rect1.Width) * (image1.Source.Width) /(image1.Width));
rcFrom.Height = (int)((rect1.Height) * (image1.Source.Height) /(image1.Height));
BitmapSource bs = new CroppedBitmap(image1.Source as BitmapSource, rcFrom);
image2.Source = bs;
}
}
#region "Mouse events"
private void image1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (isDragging == false)
{
anchorPoint.X = e.GetPosition(BackPanel).X;
anchorPoint.Y = e.GetPosition(BackPanel).Y;
isDragging = true;
}
}
private void image1_MouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
double x = e.GetPosition(BackPanel).X;
double y = e.GetPosition(BackPanel).Y;
selectionRectangle.SetValue(Canvas.LeftProperty, Math.Min(x, anchorPoint.X));
selectionRectangle.SetValue(Canvas.TopProperty, Math.Min(y, anchorPoint.Y));
selectionRectangle.Width = Math.Abs(x - anchorPoint.X);
selectionRectangle.Height = Math.Abs(y - anchorPoint.Y);
if (selectionRectangle.Visibility != Visibility.Visible)
selectionRectangle.Visibility = Visibility.Visible;
}
}
private void image1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (isDragging)
{
isDragging = false;
if(selectionRectangle.Width >0)
{
Go.Visibility = System.Windows.Visibility.Visible;
Go.IsEnabled = true;
}
if (selectionRectangle.Visibility != Visibility.Visible)
selectionRectangle.Visibility = Visibility.Visible;
}
}
private void RestRect()
{
selectionRectangle.Visibility = Visibility.Collapsed;
isDragging = false;
}
#endregion
It is cropping the wrong part.

The Margin property was not set properly to the Canvas control. It should be the same as Image control's margin properly value. If we don't set Margin to Canvas, It will take the full window size.
Xaml
<Grid x:Name="Gridimage1" Margin="0,0,411,100">
<Image Name="image1" Grid.Column="0" Height="317" HorizontalAlignment="Left" Margin="20,67,0,0" Stretch="Fill" VerticalAlignment="Top" Width="331">
</Image>
<Canvas x:Name="BackPanel" Margin="20,67,0,0">
<Rectangle x:Name="selectionRectangle" Stroke="LightBlue" Fill="#220000FF" Visibility="Collapsed" />
</Canvas>
</Grid>

<Grid x:Name="other">
<Button Content=">>" Height="23" HorizontalAlignment="Left" Margin="341,152,0,0" Name="Go" VerticalAlignment="Top" Width="41" Click="Go_Click" FontWeight="Bold" />
<Image Height="317" HorizontalAlignment="Left" Margin="403,10,-217,-7" Name="image2" Stretch="Fill" VerticalAlignment="Top" Width="331" />
</Grid>
</Grid>

Related

Horizontal dynamic listbox with insert buttons

I would like to create an horizontal dynamic listbox:
A button is visible when the mouse is between two items.
<ListBox
MinHeight="32"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
SelectionMode="Extended"
HorizontalAlignment="Stretch">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsItemsHost="True" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>
<TextBlock><Run Text="C1" /></TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock><Run Text="C2" /></TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock><Run Text="C3" /></TextBlock>
</ListBoxItem>
<ListBoxItem>
<TextBlock><Run Text="C4" /></TextBlock>
</ListBoxItem>
</ListBox>
</ListBox>
Any suggestions, please?
Thank you
EDIT
private void myElement_MouseEnter(object sender, MouseEventArgs e)
{
//change button visibility
if (sender is Grid item)
{
if (item.DataContext is DataModel data)
{
System.Diagnostics.Debug.WriteLine("myElement_MouseEnter: " + data.TextValue);
}
var border1 = (Border)item.FindName("HitTestBorder1");
var border2 = (Border)item.FindName("HitTestBorder2");
if (border1 is Border)
{
var margin = border1.Margin;
margin.Left = -item.ActualWidth;
border1.Margin = margin;
}
if (border2 is Border)
{
var margin = border2.Margin;
margin.Left = item.ActualWidth;
border2.Margin = margin;
}
}
}
The problem is that the grid width is resized after mouse_enter... So, I don't get the overlay "effect".
Here is the solution.
I created a canvas. It contains 2 borders with button inside and ZPanel is setted very high (=1000) to be on top of everything.
I change the position of these borders on MouseEnter and MouseLeave events of ListBoxItem (see ItemTemplate).
XAML
<Border Padding="10">
<Canvas x:Name="supergrid" MouseLeave="supergrid_MouseLeave">
<Border x:Name="HitTestBorder1"
Panel.ZIndex="1000"
Background="Transparent"
BorderBrush="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderThickness="0,0,0,0" >
<Button x:Name="button1"
Visibility="Hidden"
Content="+"
Height="18" Width="18" FontSize="6" Background="Red"
Click="button1_Click"
/>
</Border>
<Border x:Name="HitTestBorder2"
Panel.ZIndex="1000"
Background="Transparent"
BorderBrush="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderThickness="1,1,1,1" >
<Button x:Name="button2"
Visibility="Hidden"
Content="+"
Height="18" Width="18" FontSize="6" Background="Green"
Click="button2_Click"
/>
</Border>
<ListBox x:Name="HorizontalListBox"
ItemsSource="{Binding DataModels}"
Margin="0,0,0,0"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Background="Yellow" MouseLeave="HorizontalListBox_MouseLeave">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<!--<Setter Property="MinWidth" Value="60" />
<Setter Property="MinHeight" Value="40" />-->
<Setter Property="Background" Value="Blue" />
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="myElement"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
MouseEnter="myElement_MouseEnter"
MouseLeave="myElement_MouseLeave"
Background="White">
<TextBlock x:Name="myText"
Margin="10"
Text="{Binding TextValue}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
TextAlignment="Center" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Canvas>
</Border>
C#
public partial class MainWindow : Window
{
private DataModel currentDataModel;
public ObservableCollection<DataModel> DataModels { get; }
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.DataModels = new ObservableCollection<DataModel>();
this.DataModels.Add(new DataModel("Item1"));
this.DataModels.Add(new DataModel("Item2"));
this.DataModels.Add(new DataModel("SuperMegaHyperLong"));
this.DataModels.Add(new DataModel("Item3"));
this.DataModels.Add(new DataModel("Item4"));
this.DataModels.Add(new DataModel("123"));
this.DataModels.Add(new DataModel("Item5"));
}
private void myElement_MouseEnter(object sender, MouseEventArgs e)
{
updateOverlay((Grid)sender);
}
private void updateOverlay(Grid lbi)
{
if (lbi is Grid item) //the grid of listboxitem
{
if (item.DataContext is DataModel data)
{
Debug.WriteLine("myElement_MouseEnter: " + data.TextValue);
}
var myText = (TextBlock)item.FindName("myText");
if (myText is TextBlock)
{
Point relativePoint = myText.TransformToAncestor(supergrid)
.Transform(new Point(0, 0));
Debug.WriteLine("relativePoint: " + relativePoint.ToString());
//update left button position
double w = button1.ActualWidth;
double h = button1.ActualHeight;
double x = relativePoint.X - w / 2.0 - myText.Margin.Left;
double y = relativePoint.Y;
updateMargin(HitTestBorder1,
x,
x + w,
y + h,
y);
//update right button position
w = button2.ActualWidth;
h = button2.ActualHeight;
x = relativePoint.X - w / 2.0 - myText.Margin.Left;
x += item.ActualWidth;
y = relativePoint.Y;
updateMargin(HitTestBorder2,
x,
x + w,
y + h,
y);
//show the button
button1.Visibility = button2.Visibility = Visibility.Visible;
//the current item
if (myText.DataContext is DataModel dm)
{
this.currentDataModel = dm;
}
}
}
}
private void updateMargin(Border border, double left, double right, double bottom, double top)
{
//border = HitTestBorder2;
var margin = border.Margin;
margin.Left = left;
margin.Right = right;
margin.Top = top;
margin.Bottom = bottom;
border.Margin = margin;
Debug.WriteLine("updateMargin Left: " + left.ToString() + "Right: " + right.ToString());
}
private void myElement_MouseLeave(object sender, MouseEventArgs e)
{
//change button visibility
if (sender is Grid item)
{
if (item.DataContext is DataModel data)
{
System.Diagnostics.Debug.WriteLine("myElement_MouseLeave: " + data.TextValue);
}
//button1.Visibility = button2.Visibility = Visibility.Hidden;
}
}
private void HorizontalListBox_MouseLeave(object sender, MouseEventArgs e)
{
Debug.WriteLine("HorizontalListBox_MouseLeave");
//button1.Visibility = button2.Visibility = Visibility.Hidden;
}
private void supergrid_MouseLeave(object sender, MouseEventArgs e)
{
Debug.WriteLine("supergrid_MouseLeave: ");
button1.Visibility = button2.Visibility = Visibility.Hidden;
// => :D
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("LEFT INSERT");
int idx = this.DataModels.IndexOf(currentDataModel);
DataModel newDataModel = new DataModel($"Item{this.DataModels.Count}");
this.DataModels.Insert(idx, newDataModel);
button1.Visibility = button2.Visibility = Visibility.Hidden;
}
private void button2_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("RIGHT INSERT");
int idx = this.DataModels.IndexOf(currentDataModel);
this.DataModels.Insert(idx+1, new DataModel($"Item{this.DataModels.Count}"));
button1.Visibility = button2.Visibility = Visibility.Hidden;
}
}
public class DataModel
{
public string TextValue { get; set; }
public DataModel(string textValue)
{
this.TextValue = textValue;
}
}
As you can see, there is place for improvements (like select the new ListBoxItem). Disable the buttons when we drag, animation, delay, etc.

How to remove a DropShadowEffect in code?

I have a method which draws lines in a canvas like this:
public void drawoncanvas(double[] coord, string fullkey)
{
myLine = new Line();
myLine.X1 = coord[0];
myLine.X2 = coord[2];
myLine.Y1 = coord[1];
myLine.Y2 = coord[3];
MainWindow.mycanvas.Children.Add(myLine);
myLine.MouseEnter += mymouse; //add MousEnter Event
myLine.MouseLeave += mymouseleave; //add MouseLeave Event
}
The MouseEnter Event then adds a DropShadowEffect to the line that triggers the event:
public void mymouse(object sender, MouseEventArgs e)
{
Line thisline = sender as Line;
thisline.Effect = new DropShadowEffect{Color = new Color { A = 255, R = 255, G = 255, B = 0 }, Direction = 320,ShadowDepth = 0, Opacity = 1};
}
This works fine. But now I want to remove this effect as soon as the mouse cursor is not anymore over the line:
public void mymouseleave(object sender, MouseEventArgs e)
{
Line thisline = sender as Line;
thisline.Effect = null; //this doesn't do anything
}
I know this is a is probably a really simple question but I couldn't find any solution so far.
EDIT:
Ok I found what causes the problem, still don't know a solution though: I don't only create the dropshadow in the MouseEnter event but also display a tootltip, so my full Code is actually:
public void drawoncanvas(double[] coord, string fullkey)
{
myLine = new Line();
myLine.Stroke = Brushes.Red;
myLine.X1 = coord[0];
myLine.X2 = coord[2];
myLine.Y1 = coord[1];
myLine.Y2 = coord[3];
myLine.Tag = fullkey;
MainWindow.mycanvas.Children.Add(myLine);
myLine.MouseEnter += mymouse;
myLine.MouseLeave += mymouseleave;
}
ToolTip tt = new ToolTip();
public void mymouse(object sender, MouseEventArgs e)
{
Line thisline = sender as Line;
string data = Convert.ToString(thisline.Tag);
string[] splitdata = data.Split('/');
tt.Content = String.Concat(splitdata[0], " -> ", splitdata[3] ,"kt -> ", splitdata[1]);
tt.StaysOpen = false;
tt.IsOpen = true; //the removing of the shadow on MouseLeave works when I comment this line out
thisline.Effect = new DropShadowEffect{Color = new Color { A = 255, R = 255, G = 255, B = 0 }, Direction = 320,ShadowDepth = 0, Opacity = 1};
}
public void mymouseleave(object sender, MouseEventArgs e)
{
Line thisline = sender as Line;
tt.IsOpen = false;
thisline.Effect = null;
}
If I simply comment out the tt.IsOpen = true; and do not display the tooltip it all works fine.....I'm really confused.
EDIT 2:
Here the XAML:
<Window x:Class="mapO1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:mapO1"
Title="mapO1" Height="600" Width="750" WindowStartupLocation="CenterScreen" SizeChanged="MainWindow_SizeChanged">
<Grid>
<Grid x:Name="mygrid">
<local:ZoomBorder x:Name="border" ClipToBounds="True" Background="Black">
<Grid Name="maingrid">
<Image Name="image1" />
<Canvas Name="mycanvas" HorizontalAlignment="Left" VerticalAlignment="Top" ClipToBounds="False"/>
</Grid>
</local:ZoomBorder>
<Button x:Name="button1" Content="Fullscreen on/off" HorizontalAlignment="Right" Height="18" Margin="0,20,50,0" VerticalAlignment="Top" Opacity="0.5" Width="108" FontWeight="Bold" Click="button1_Click"/>
<ComboBox x:Name="comboBox1" Height="24" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150" Margin="10,20,0,0" Opacity="0.5" FontWeight="Bold" Text="Select Period" SelectionChanged="comboBox1_SelectionChanged"/>
<ComboBox x:Name="comboBox2" Height="24" HorizontalAlignment="Left" VerticalAlignment="Top" Width="150" Margin="10,60,0,0" FontWeight="Bold" Opacity="0.5" Text="Select Stream" DropDownClosed="comboBox2_DropDownClosed"/>
</Grid>
</Grid>
</Window>

C# WPF - how to prevent image to be dragged outside canvas

i tried this Answer and implement it to my code, and here is my code :
XAML
<Window x:Class="DSLayout.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:tk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:local="clr-namespace:DSLayout"
Title="MainWindow" Height="720" Width="1280" ResizeMode="NoResize">
<Window.Resources>
<local:BrushColorConverter x:Key="BrushColorConverter"/>
</Window.Resources>
<Grid>
<Border BorderBrush="Silver" BorderThickness="1" Name="borderHeader" Margin="12,12,12,636" />
<Border BorderBrush="Silver" BorderThickness="1" Name="borderEditor" Margin="12,69,850,12">
<Canvas>
<Border BorderBrush="Silver" BorderThickness="1" Canvas.Left="24" Canvas.Top="20" Height="59" Name="border1" Width="355"></Border>
<Canvas Height="59" Canvas.Left="26" Canvas.Top="20"></Canvas>
<TextBlock Name="textBlock1" Text="Color Palette" Height="31" Width="197" FontSize="22" Canvas.Left="40" Canvas.Top="34" />
<tk:ColorPicker x:Name="ColorPalette" ColorMode="ColorCanvas"
SelectedColor="{Binding ElementName=Layout,
Path=Background,
Converter={StaticResource BrushColorConverter}}"
Canvas.Left="243" Canvas.Top="34" Height="31" />
<Button Grid.Row="1" Content="Add Image" Click="AddButtonClick" Canvas.Left="24" Canvas.Top="100" Height="43" Width="104" />
<Border BorderBrush="Silver" BorderThickness="1" Canvas.Left="24" Canvas.Top="227" Height="350" Name="border3" Width="355">
<Canvas>
<TextBlock Canvas.Left="15" Canvas.Top="27" Height="23" Name="textBlock2" Text="X-Pos " FontSize="16" Width="53" />
<TextBlock Canvas.Left="174" Canvas.Top="27" FontSize="16" Height="23" Name="textBlock3" Text="Y-Pos " Width="53" />
<Label Name="posX" Height="23" Width="83" Canvas.Left="74" Canvas.Top="27" />
<Label Name="posY" Canvas.Left="233" Canvas.Top="27" Height="23" Width="83" />
<TextBlock Canvas.Left="15" Canvas.Top="68" FontSize="16" Height="23" Name="textBlock4" Text="Width" Width="53" />
<TextBlock Canvas.Left="174" Canvas.Top="68" FontSize="16" Height="23" Name="textBlock5" Text="Height" Width="53" />
<Label Name="imgHeight" Canvas.Left="74" Canvas.Top="68" Height="23" Width="83" />
<Label Name="imgWidth" Canvas.Left="233" Canvas.Top="68" Height="23" Width="83" />
<!--<TextBlock Canvas.Left="15" Canvas.Top="169" FontSize="16" Height="23" Name="textBlock4" Text="Height" Width="53" />
<TextBlock Canvas.Left="174" Canvas.Top="169" FontSize="16" Height="23" Name="textBlock5" Text="Width" Width="53" />
<TextBox Canvas.Left="74" Canvas.Top="169" Height="23" Name="textBox3" Width="83" />
<TextBox Canvas.Left="233" Canvas.Top="169" Height="23" Name="textBox4" Width="83" />-->
</Canvas>
</Border>
</Canvas>
</Border>
<Border BorderBrush="Silver" BorderThickness="1" Name="borderLayout" Margin="446,69,12,12">
<Canvas x:Name="Layout" Background="White" AllowDrop="True" ClipToBounds="True"
MouseLeftButtonDown="MouseLeftButtonDown"
MouseLeftButtonUp="MouseLeftButtonUp"
MouseMove="MouseMove">
</Canvas>
</Border>
</Grid>
CS
namespace DSLayout
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public int imgX { get; set; }
public int imgY { get; set; }
private void AddButtonClick(object sender, RoutedEventArgs e)
{
var dialog = new Microsoft.Win32.OpenFileDialog();
dialog.Filter =
"Image Files (*.jpg; *.png; *.jpeg; *.gif; *.bmp)|*.jpg; *.png; *.jpeg; *.gif; *.bmp";
if ((bool)dialog.ShowDialog())
{
var bitmap = new BitmapImage(new Uri(dialog.FileName));
var image = new Image { Source = bitmap };
this.imgX = bitmap.PixelWidth;
this.imgY = bitmap.PixelWidth;
Canvas.SetLeft(image, 0);
Canvas.SetTop(image, 0);
Layout.Children.Add(image);
imgHeight.Content = bitmap.PixelHeight;
imgWidth.Content = bitmap.PixelWidth;
}
}
private Image draggedImage;
private Point mousePosition;
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var image = e.Source as Image;
if (image != null && Layout.CaptureMouse())
{
mousePosition = e.GetPosition(Layout);
draggedImage = image;
Panel.SetZIndex(draggedImage, 1);
}
}
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (draggedImage != null)
{
Layout.ReleaseMouseCapture();
Panel.SetZIndex(draggedImage, 0);
draggedImage = null;
}
}
private void MouseMove(object sender, MouseEventArgs e)
{
if (draggedImage != null)
{
var position = e.GetPosition(Layout);
var offset = position - mousePosition;
mousePosition = position;
if (mousePosition.X > 0 && mousePosition.Y > 0)
{
Canvas.SetLeft(draggedImage, Canvas.GetLeft(draggedImage) + offset.X);
Canvas.SetTop(draggedImage, Canvas.GetTop(draggedImage) + offset.Y);
}
posX.Content = Canvas.GetLeft(draggedImage);
posY.Content = Canvas.GetTop(draggedImage);
}
}
}
}
so i tried using the ClipToBound="True" but it'll missing if i drag to outside the canvas. so i tried to limit it using if (mousePosition.X > 0 && mousePosition.Y > 0) works but not that i want because it will go outside the canvas if i drag it to the left and i drag from the right point of the image.
my idea is to make the draggedImage to be my cursor so with if (mousePosition.X > 0 && mousePosition.Y > 0) it will prevent draggedImage to go outside the canvas. is that possible to do that?
or any simple idea to solve this?
EDIT :
i tried using this code but it works but its not really good because when i drag it out side the canvas it'll move like bouncy from pos -1 to 0.
if (Canvas.GetLeft(draggedImage) <= 0)
{
Canvas.SetLeft(draggedImage, 0);
}
if (Canvas.GetTop(draggedImage) <= 0)
{
Canvas.SetTop(draggedImage, 0);
}
if (Canvas.GetLeft(draggedImage) + this.imgX >= 800)
{
Canvas.SetLeft(draggedImage, 800 - this.imgX);
}
if (Canvas.GetTop(draggedImage) +this.imgY >= 600)
{
Canvas.SetTop(draggedImage, 600 - this.imgY);
}
When you drag an item you change it's X and Y position by specifying Canvas's attached properties Canvas.Left and Canvas.Top. So it is easy to ensure that the dragged element does not get dragged outside it's panel.
double canvasSize = 800;
double newLeft = Canvas.GetLeft(draggedImage) + offset.X;
double newTop = Canvas.GetTop(draggedImage) + offset.Y;
if (newLeft < 0)
newLeft = 0;
else if (newLeft + draggedImage.ActualWidth > canvasSize)
newLeft = canvasSize - draggedImage.ActualWidth;
if (newTop < 0)
newTop = 0;
else if (newTop + draggedImage.ActualHeight > canvasSize)
newTop = canvasSize - draggedImage.ActualHeight;
Canvas.SetLeft(draggedImage, newLeft);
Canvas.SetTop(draggedImage, newTop);
This will check if the element you drag is going outside of the Canvas.

Creating and using a new Brush or color using sliders and dependency properties in C#

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>

Setting an XAML Window always on top (but no TopMost property)

I am developing an application based on OptiTrack SDK (from NaturalPoint). I need to run the application window as "Always on Top". The window is designed in XAML and is controled in the class "CameraView" but it does not seem to include a "TopMost" property or equivalent. Attached are the code of "CameraView.xaml.cs" and the code of "CameraView.xaml" that are part of OptiTrack SDK (NaturalPoint) called "Single_Camera_CSharp_.NET_3.0".
One could expect the class CameraView to contain properties or members to set the position of the window on the screen or to set it to TopMost but as far as searched I found nothing. I wonder what I should do.
Thank you,
Brian
================
"CameraView.xaml.cs"
using System;
using System.IO;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Windows.Threading;
namespace TestProject
{
public partial class CameraView
{
private const int NP_OPTION_OBJECT_COLOR_OPTION = 3;
private const int NP_OPTION_VIDEO_TYPE = 48;
private const int NP_OPTION_NUMERIC_DISPLAY_ON = 71;
private const int NP_OPTION_NUMERIC_DISPLAY_OFF = 72;
private const int NP_OPTION_FETCH_RLE = 73;
private const int NP_OPTION_FETCH_GRAYSCALE = 74;
private const int NP_OPTION_FRAME_DECIMATION = 52;
private const int NP_OPTION_INTENSITY = 50;
private const int NP_OPTION_SEND_EMPTY_FRAMES = 41;
private const int NP_OPTION_THRESHOLD = 5;
private const int NP_OPTION_EXPOSURE = 46;
private const int NP_OPTION_SEND_FRAME_MASK = 73;
private const int NP_OPTION_TEXT_OVERLAY_OPTION = 74;
// public delegate void OnCameraViewCreate(CameraView camera);
// public static OnCameraViewCreate onCameraViewCreate;
private System.Drawing.Bitmap raw = new System.Drawing.Bitmap(353, 288, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
private int mFrameCounter;
private int mDisplayCounter;
private DispatcherTimer timer1 = new DispatcherTimer();
private bool mVideoFrameAvailable = false;
private int mNumeric = -1;
private bool mGreyscale = false;
private bool mOverlay = true;
public CameraView()
{
this.InitializeComponent();
timer1.Interval = new TimeSpan(0, 0, 0, 0, 10);
timer1.Tick += new EventHandler(timer1_Tick);
}
public int Numeric
{
get { return mNumeric; }
set
{
mNumeric = value % 100;
if (mNumeric >= 0)
{
if (Camera != null)
Camera.SetOption(NP_OPTION_NUMERIC_DISPLAY_ON, value % 100);
}
}
}
private bool CameraRunning = false;
private OptiTrack.NPCamera mCamera;
public OptiTrack.NPCamera Camera
{
get { return mCamera; }
set
{
if (mCamera == value) return; //== Don't do anything if you're assigning the same camera ==
if (mCamera != null)
{
//== Shut the selected camera down ==<<
if (CameraRunning)
{
CameraRunning = false;
mCamera.Stop();
mCamera.FrameAvailable -= FrameAvailable;
}
}
mCamera = value;
if (mCamera == null)
{
mNumeric = -1;
}
else
{
serialLabel.Content = "Camera "+mCamera.SerialNumber.ToString(); //mNumeric.ToString();
}
}
}
private void FrameAvailable(OptiTrack.NPCamera Camera)
{
mFrameCounter++;
try
{
OptiTrack.NPCameraFrame frame = Camera.GetFrame(0);
int id = frame.Id;
if (CameraRunning)
{
GetFrameData(Camera, frame);
}
frame.Free();
}
catch (Exception)
{
int r = 0;
r++;
}
}
private void GetFrameData(OptiTrack.NPCamera camera, OptiTrack.NPCameraFrame frame)
{
BitmapData bmData = raw.LockBits(new System.Drawing.Rectangle(0, 0, raw.Width, raw.Height),
ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
int stride = bmData.Stride;
System.IntPtr bufferPtr = bmData.Scan0;
unsafe
{
byte* buffer = (byte*)(void*)bufferPtr;
camera.GetFrameImage(frame, bmData.Width, bmData.Height, bmData.Stride, 32, ref buffer[0]);
}
raw.UnlockBits(bmData);
mVideoFrameAvailable = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (CameraRunning && mVideoFrameAvailable)
{
mVideoFrameAvailable = false;
cameraImage.Source = Img(raw);
mDisplayCounter++;
}
}
private System.Windows.Media.ImageSource Img(System.Drawing.Bitmap img)
{
System.Drawing.Imaging.BitmapData bmData = img.LockBits(new System.Drawing.Rectangle(0, 0, img.Width, img.Height),
System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
System.Windows.Media.Imaging.BitmapSource bitmap = System.Windows.Media.Imaging.BitmapSource.Create(
img.Width, img.Height, 96, 96, PixelFormats.Bgra32,
System.Windows.Media.Imaging.BitmapPalettes.WebPalette,
bmData.Scan0, bmData.Stride * bmData.Height, bmData.Stride);
img.UnlockBits(bmData);
return bitmap;
}
private void startStopButton_Click(object sender, RoutedEventArgs e)
{
if (CameraRunning)
StopCamera();
else
StartCamera();
}
public void StartCamera()
{
if (Camera != null)
{
mFrameCounter = 0;
mDisplayCounter = 0;
Camera.FrameAvailable += FrameAvailable;
Camera.SetOption(NP_OPTION_VIDEO_TYPE, 0);
Camera.SetOption(NP_OPTION_FRAME_DECIMATION, 1);
Camera.SetOption(NP_OPTION_INTENSITY, 0);
Camera.SetOption(NP_OPTION_EXPOSURE, 10);
Camera.SetOption(NP_OPTION_THRESHOLD, 50);
Camera.SetOption(NP_OPTION_OBJECT_COLOR_OPTION, 0);
SetOverlayOption();
SetGreyscaleOption();
timer1.Start();
Camera.Start();
CameraRunning = true;
this.Numeric = mNumeric;
startStopButton.Content = "Stop Camera";
}
}
private void SetGreyscaleOption()
{
if(mGreyscale)
Camera.SetOption(NP_OPTION_VIDEO_TYPE, 1);
else
Camera.SetOption(NP_OPTION_VIDEO_TYPE, 0);
}
private void SetOverlayOption()
{
if(mOverlay)
Camera.SetOption(NP_OPTION_TEXT_OVERLAY_OPTION, 255);
else
Camera.SetOption(NP_OPTION_TEXT_OVERLAY_OPTION, 0);
}
public void StopCamera()
{
if (Camera != null)
{
Camera.Stop();
timer1.Stop();
CameraRunning = false;
Camera.FrameAvailable -= FrameAvailable;
Camera.SetOption(NP_OPTION_NUMERIC_DISPLAY_OFF, 0);
startStopButton.Content = "Start Camera";
}
}
private void greyscaleButton_Click(object sender, RoutedEventArgs e)
{
if(mGreyscale)
mGreyscale = false;
else
mGreyscale = true;
SetGreyscaleOption();
}
private void OverlayButton_Click(object sender, RoutedEventArgs e)
{
if(mOverlay)
mOverlay = false;
else
mOverlay = true;
SetOverlayOption();
}
private void exposureSlider_ValueChanged(object sender, RoutedEventArgs e)
{
if (mCamera!=null)
{
mCamera.SetOption(NP_OPTION_EXPOSURE, (int) this.exposureSlider.Value);
}
}
private void thresholdSlider_ValueChanged(object sender, RoutedEventArgs e)
{
if (mCamera != null)
{
mCamera.SetOption(NP_OPTION_THRESHOLD, (int)this.thresholdSlider.Value);
}
}
private void optionsButton_Click(object sender, RoutedEventArgs e)
{
if (!propertyPanel.IsVisible)
propertyPanel.Visibility = Visibility.Visible;
else
propertyPanel.Visibility = Visibility.Collapsed;
}
}
}
================
"CameraView.xaml"
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="TestProject.CameraView"
x:Name="CameraView1"
Width="Auto" Height="Auto"
xmlns:d="http://schemas.microsoft.com/expression/blend/2006"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
>
<Grid x:Name="LayoutRoot" Width="Auto" Height="Auto">
<Grid.Background>
<x:Null/>
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="113.904"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="26.667"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Margin="0,0,0,0" Grid.ColumnSpan="2">
<Rectangle RadiusX="1.25" RadiusY="1.25" Margin="0,0,0,0" VerticalAlignment="Stretch">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.492,0.149" StartPoint="0.492,0.843">
<GradientStop Color="#FF000000" Offset="0"/>
<GradientStop Color="#FF23283F" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
<Rectangle.Stroke>
<LinearGradientBrush EndPoint="0.291,-4.231" StartPoint="1.668,18.025">
<GradientStop Color="#FF000000" Offset="0"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Stroke>
</Rectangle>
<Rectangle RadiusX="3.333" RadiusY="3.333" Opacity="0.13" Margin="0,0,0,13">
<Rectangle.Fill>
<SolidColorBrush Color="#FFFFFFFF"/>
</Rectangle.Fill>
<Rectangle.Stroke>
<x:Null/>
</Rectangle.Stroke>
</Rectangle>
</Grid>
<Image Margin="0,0,0,0" x:Name="cameraImage" Grid.ColumnSpan="2" Grid.Row="1"/>
<Label x:Name="serialLabel" FontSize="10" FontWeight="Bold" Foreground="#FFDEDADA" Content="Camera 10024" HorizontalAlignment="Right" Margin="0,0,4,0" VerticalAlignment="Top" Grid.Column="1">
<Label.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="#FF000000" GlowSize="4" Opacity="0.7"/>
</Label.BitmapEffect>
</Label>
<WrapPanel Margin="3,3,3,3">
<Button HorizontalAlignment="Stretch" Margin="0,0,0,0" x:Name="startStopButton" Width="100" Height="Auto" BorderThickness="0,0,0,0" Content="Start Camera" Click="startStopButton_Click"/>
<Button x:Name="optionsButton" Width="61.474" Height="Auto" BorderThickness="0,0,0,0" Content="Options" Click="optionsButton_Click"/>
</WrapPanel>
<Grid Visibility="Visible" d:LayoutOverrides="HorizontalAlignment, VerticalAlignment" HorizontalAlignment="Right" Margin="0,0,16,16" x:Name="propertyPanel" VerticalAlignment="Bottom" Width="169.237" Height="81.455" Grid.ColumnSpan="2" Grid.Row="1">
<Rectangle Stroke="#FFFFFFFF" StrokeThickness="3" Margin="0,0,0,0">
<Rectangle.BitmapEffect>
<DropShadowBitmapEffect/>
</Rectangle.BitmapEffect>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
<GradientStop Color="#FF1E212F" Offset="0"/>
<GradientStop Color="#FF313551" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Slider HorizontalAlignment="Stretch" Margin="62.633,5,4.681,0" x:Name="exposureSlider" VerticalAlignment="Top" Width="Auto" Height="Auto" Orientation="Horizontal" Maximum="255" ValueChanged="exposureSlider_ValueChanged"/>
<Label x:Name="serialLabel_Copy" FontSize="10" FontWeight="Bold" Foreground="#FFDEDADA" Content="Exposure" HorizontalAlignment="Left" Margin="3.853,3.853,0,0" VerticalAlignment="Top" Width="57.352">
<Label.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="#FF000000" GlowSize="4" Opacity="0.7"/>
</Label.BitmapEffect>
</Label>
<Label x:Name="serialLabel_Copy1" FontSize="10" FontWeight="Bold" Foreground="#FFDEDADA" Content="Threshold" d:LayoutOverrides="Height" HorizontalAlignment="Left" Margin="3.853,27.691,0,0" VerticalAlignment="Top" Width="59.829">
<Label.BitmapEffect>
<OuterGlowBitmapEffect GlowColor="#FF000000" GlowSize="4" Opacity="0.7"/>
</Label.BitmapEffect>
</Label>
<Slider x:Name="thresholdSlider" Width="Auto" Orientation="Horizontal" Maximum="253" d:LayoutOverrides="Height, Margin" Margin="62.633,27.691,4.681,0" VerticalAlignment="Top" Minimum="54" Value="54" ValueChanged="thresholdSlider_ValueChanged"/>
<Button x:Name="greyScaleButton" Width="75.333" Content="Greyscale" Click="greyscaleButton_Click" HorizontalAlignment="Left" Height="21" d:LayoutOverrides="Height" Margin="8,53.761,0,0" VerticalAlignment="Top"/>
<Button x:Name="Overlay" Height="21" Content="Overlay" Click="OverlayButton_Click" d:LayoutOverrides="Height" HorizontalAlignment="Right" Margin="0,53.761,8,0" VerticalAlignment="Top" Width="64"/>
</Grid>
</Grid>
</UserControl>
The Topmost property exists on the Window class: http://msdn.microsoft.com/en-us/library/system.windows.window.topmost.aspx.
Your CameraView class is derived from UserControl, which is a kind of control that sits inside a Window (or other container such as a Page, but that's not important here). UserControl doesn't have a Topmost property because it doesn't appear independently on the desktop.
Host your CameraView in a Window and set the Window.Topmost:
<!-- MyWindow.xaml -->
<Window ...
xmlns:local="clr-namespace:TestProject"
Topmost="True">
<local:CameraView />
</Window>
where the ellipses represent the default gunk like x:Class and WPF xmlns declarations that Visual Studio creates for you.
In the UserControl code behind, you can get a reference to the window that is hosting it, then set the Topmost property. Example,
Window parent = Window.GetWindow(this);
parent.Topmost = true;
This is UserControl. You can set TopMost property for Windows only

Categories