I have a predefined User Control from a third party library. I would like to cut off a region from this User Control and use it in the Main window. Clipping is easily done with the Clip property of a UIElement but then the resizing does not work for this single segment. Is it possible to cut from a UIElement or User Control and use only this region for measuring, resizing and rendering of the component?
Please see a sample below :
XAML
<Window x:Class="WpfStackOverflow.Window12"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfStackOverflow"
Title="Window12" Height="300" Width="600">
<Canvas>
<Button Content="Press" Height="35" Width="75" Canvas.Left="29" Canvas.Top="43" Click="Button_Click_1">
<Button.Background>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FF62CFB6" Offset="0"/>
<GradientStop Color="#FFEBEBEB" Offset="0.5"/>
<GradientStop Color="#FF91B3E4" Offset="0.391"/>
<GradientStop Color="#FFF11278" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
<Button.Clip>
<GeometryGroup>
<EllipseGeometry RadiusX="50" RadiusY="25"/>
<RectangleGeometry Rect="55 20 75 35"/>
</GeometryGroup>
</Button.Clip>
</Button>
<Path x:Name="Pth" Width="75" Height="35" Fill="AliceBlue" Canvas.Top="80" Canvas.Left="300" Stretch="None" Stroke="#FF7C4444" Data=""/>
<Thumb Width="10" Height="10" Canvas.Left="217" Canvas.Top="34" DragDelta="Thumb_DragDelta_1"/>
<TextBlock Canvas.Left="217" TextWrapping="Wrap" Text="Drag this Thumb to right" Canvas.Top="10"/>
<TextBlock Canvas.Left="10" TextWrapping="Wrap" Text="Click this button" Canvas.Top="10"/>
</Canvas>
</Window>
CODE
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Media;
namespace WpfStackOverflow
{
/// <summary>
/// Interaction logic for Window12.xaml
/// </summary>
public partial class Window12 : Window
{
public Window12()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var c = VisualTreeHelper.GetClip(sender as Button);
Pth.Data = c;
}
double scaleX=1, scaleY=1;
private void Thumb_DragDelta_1(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
if (Pth.LayoutTransform == null)
Pth.LayoutTransform = new ScaleTransform(1, 1);
scaleX += e.HorizontalChange;
scaleY += e.HorizontalChange;
Pth.LayoutTransform = new ScaleTransform(scaleX, scaleY);
System.Diagnostics.Debug.WriteLine((1 + e.HorizontalChange).ToString());
Thickness margin = (sender as Thumb).Margin;
(sender as Thumb).Margin = new Thickness(margin.Left + e.HorizontalChange, margin.Top, margin.Right, margin.Bottom);
}
}
}
Related
when i run Main_win.xaml using a function, wpf page not showing any content
App.xaml:
<Application x:Class="test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:salesandwarehousingsystem"
ShutdownMode="OnExplicitShutdown"
Startup = "Application_Startup" >
</Application>
App.xaml.cs:
private void Application_Startup(object sender, StartupEventArgs e)
{
Main_win main_Win = new Main_win();
main_Win.ShowDialog();}
Main_win.xaml:
<Window x:Class="test.window.Main_win"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:salesandwarehousingsystem.window"
xmlns:custom="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon"
mc:Ignorable="d"
Title="Main_win" Height="660" Width="1300">
<Grid>
<Ribbon >
<Ribbon.QuickAccessToolBar>
<RibbonQuickAccessToolBar >
<RibbonSplitButton >
<RibbonSplitMenuItem Header=" About Us"/>
<RibbonSplitMenuItem Header=" Contact Us"/>
<RibbonSplitMenuItem Header=" Exit"/>
</RibbonSplitButton>
</RibbonQuickAccessToolBar>
</Ribbon.QuickAccessToolBar>
<Button Content="Button" Height="21" Width="136"/>
</Ribbon>
<Button Content="Button" Margin="561,282,422,282"/>
</Grid>
and result:
no matter what you add... button or any object...same result
I ran the code you showed.
It displayed a populated window, albeit with binding errors.
For errors fixed, inherit Main_win from RibbonWindow.
<RibbonWindow x:Class="test.window.Main_win"
public partial class Main_win : RibbonWindow
Win_Login.xaml.cs
public partial class Win_login : RibbonWindow
{
public Win_login(object #object)
:this() // Calling the default constructor so that there is no code duplication.
{
}
public Win_login()
{
// XAML processing is performed by this method.
// Therefore, it is necessary to ensure its call in any constructor.
InitializeComponent();
}
#EldHasp thanks for your help. problem with Main_win page solved.
but i have another page with this problem
Win_Login.xaml.cs :
public partial class Win_login : RibbonWindow
{
public Win_login(object #object)
{
InitializeComponent();
}
public Win_login()
{
}
private void btn_login_Click(object sender, RoutedEventArgs e)
{
if (txt_username.Text == "a" && txt_password.Password == "123")
{
Main_win Mainwindow = new Main_win();
}
else
{
MessageBox.Show("user not found");
}
}
private void btn_Exit_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}
win_login.xaml :
<RibbonWindow x:Class="salesandwarehousingsystem.Win_login"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:salesandwarehousingsystem"
mc:Ignorable="d"
Title="Win_login" Height="400" Width="600" Background="Transparent" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterScreen" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Stroke="Black" Margin="20,10,0,10" RadiusX=" 15" RadiusY=" 15">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF134116"/>
<GradientStop Color="#FF68E370" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Rectangle Stroke="Black" Margin="20,10,0,290" RadiusX=" 15" RadiusY=" 15">
<Rectangle.Effect>
<DropShadowEffect/>
</Rectangle.Effect>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF0F510E" Offset="1"/>
<GradientStop Color="#FF1FAE1E" Offset="0"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<Label Content="test" HorizontalAlignment="Center" Height="41" Margin="0,19,0,0" VerticalAlignment="Top" Width="491" FontFamily="Segoe Script" FontSize="28" Foreground="#FF0C1462"/>
<Label Content="Login Form" HorizontalAlignment="Left" Margin="54,65,0,0" VerticalAlignment="Top" Height="45" Width="156" FontSize="24" FontFamily="Segoe Script" Foreground="#FF0C1462"/>
<Label Content="USER NAME:" HorizontalAlignment="Left" Margin="30,150,0,0" VerticalAlignment="Top" Height="34" Width="91" FontFamily="Arial Black"/>
<Label Content="PASSWORD :" HorizontalAlignment="Left" Margin="30,200,0,0" VerticalAlignment="Top" Height="39" Width="91" FontFamily="Arial Black"/>
<TextBox x:Name="txt_username" HorizontalAlignment="Left" Margin="150,154,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" Height="26" FontFamily="Arial Narrow" Foreground="White">
<TextBox.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFB3B0E8" Offset="1"/>
</LinearGradientBrush>
</TextBox.Background>
</TextBox>
<Button x:Name="btn_login" Content="LOGIN" HorizontalAlignment="Left" Margin="30,299,0,0" VerticalAlignment="Top" Height="37" Width="91" Foreground="White" Click="btn_login_Click" >
<Button.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF8F614F" Offset="0.993"/>
<GradientStop Color="#FF3F1010"/>
<GradientStop Color="#FF614542" Offset="0.347"/>
</LinearGradientBrush>
</Button.Background>
</Button>
<Button x:Name="btn_Exit" Content="EXIT" HorizontalAlignment="Left" Margin="150,299,0,0" VerticalAlignment="Top" Height="37" Width="91" Foreground="White" Click="btn_Exit_Click">
<Button.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF8F614F" Offset="0.993"/>
<GradientStop Color="#FF3F1010"/>
<GradientStop Color="#FF614542" Offset="0.347"/>
</LinearGradientBrush>
</Button.Background>
</Button>
<PasswordBox x:Name="txt_password" HorizontalAlignment="Left" Margin="150,200,0,0" VerticalAlignment="Top" Width="120" Height="29" FontFamily="Arial Narrow" Foreground="White">
<PasswordBox.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FFB3B0E8" Offset="1"/>
</LinearGradientBrush>
</PasswordBox.Background>
</PasswordBox>
</Grid>
and now this page don't have any binding issues...
I have the following Viewbox in MainWindow.Xaml:
<Viewbox x:Name="R1C1Viewbox" Grid.Row="1" Grid.Column="2"
Grid.ColumnSpan="1" Grid.RowSpan="1">
<Border x:Name="R1C1Border" BorderBrush="White" CornerRadius="3"
BorderThickness="2" Background="White"
Height="40" Width="40" Margin="0,3,3,0">
<Grid x:Name="R1C1Grid">
<TextBlock x:Name="R1C1TextBlock1" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="Arial" FontWeight="Bold" Text="+" FontSize="22"></TextBlock>
<Polygon x:Name="R1C1LED"
Points="0,0 15,0 0,15"
Stroke="#FFED1C24"
StrokeThickness="1">
<Polygon.Fill>
<RadialGradientBrush>
<GradientStop Color="White" Offset="2.5"/>
<GradientStop Color="Black"/>
</RadialGradientBrush>
</Polygon.Fill>
</Polygon>
<Button x:Name="R1C1Button" Background="Transparent"
BorderBrush="Transparent">
</Button>
</Grid>
</Border>
</Viewbox>
In my code behind, I define 2 RadialGradientBrushes for the Polygon.Fill property:
public static RadialGradientBrush ledOn = new RadialGradientBrush();
public static RadialGradientBrush ledOff = new RadialGradientBrush();
ledOn.GradientStops.Add(new GradientStop(Colors.Red, .8));
ledOn.GradientStops.Add(new GradientStop(Colors.White, 0));
ledOff.GradientStops.Add(new GradientStop(Colors.White, 2.5));
ledOff.GradientStops.Add(new GradientStop(Colors.Black, 0));
If I load the viewbox only from MainWindow.xaml, I can use:
R1C1LED.Fill = ledOn;
or
R1C1LED.Fill = ledOff;
and the fill changes as expected. If I load the exact same xaml from a file using XamlReader(), the Viewbox displays exactly as expected but using the code behind to change the fill as above doesn't change the fill and no errors are generated.
Example code:
private void OnTest(object sender, RoutedEventArgs e)
{
var xaml =
#"<Window
xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:d='http://schemas.microsoft.com/expression/blend/2008'
xmlns:mc='http://schemas.openxmlformats.org/markup-compatibility/2006'
mc:Ignorable='d'
Title='WPF App' Height='450' Width='800'>
<StackPanel Orientation='Vertical'>
<Button x:Name='R1C1LED' Content='Load Data' />
</StackPanel>
</Window>";
var win = (Window)XamlReader.Parse(xaml);
var button = (Button)win.FindName("R1C1LED");
button.Background = Brushes.Red;
button.Click += (obj, args) => { MessageBox.Show("Hi!"); };
win.Show();
}
I have an Image viewer implemented using ScrollViewer
.XAML
<ScrollViewer Name="viewImg" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" >
<Image Name="bigImage"
Source="/JoyOs.Media;component/img/Plugins/Photos/PHOTO.png"
PreviewMouseLeftButtonUp="ImageMouseLeftButtonUp"
PreviewMouseLeftButtonDown="ImageMouseLeftButtonDown"
PreviewMouseMove="ImageMouseMove" Stretch="Uniform"></Image>
</ScrollViewer>
ScrollViewer class .cs file
public partial class ImageList
{
private void ImageMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var img = (Image)sender;
img.ReleaseMouseCapture();
}
private void ImageMouseMove(object sender, MouseEventArgs e)
{
var img = (Image)sender;
if (!img.IsMouseCaptured) return;
Vector v = _startImgMove - e.GetPosition(viewImg);
viewImg.ScrollToHorizontalOffset(_originImgMove.X - v.X);
viewImg.ScrollToVerticalOffset(_originImgMove.Y - v.Y);
}
private void ImageMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var img = (Image)sender;
img.CaptureMouse();
_startImgMove = e.GetPosition(viewImg);
_originImgMove = new Point(viewImg.HorizontalOffset, viewImg.VerticalOffset);
}
}
I want zoom features implemented in it.Hence I tried to use ZoomBorder.cs class from this.
How to use ZoomBorder.cswith ScrollViewer ?
I tried Without ScrollViewer with only ZoomBorder.cs like this.
<local:ZoomBorder x:Name="border" ClipToBounds="True" Background="Gray">
<Image Name="bigImage"
Source="/JoyOs.Media;component/img/Plugins/Photos/PHOTO.png"
PreviewMouseLeftButtonUp="ImageMouseLeftButtonUp"
PreviewMouseLeftButtonDown="ImageMouseLeftButtonDown"
PreviewMouseMove="ImageMouseMove" Stretch="Uniform"></Image>
</local:ZoomBorder>
I can't answer the question for ZoomBorder's, but I have implemented zoom functionality myself in a different way. I have a ViewBox, which I bind the ScaleTransform of to a value in my ViewModel. Changing the value in my ViewModel then causes the contents of the ViewBox to zoom in and out depending on the value.
<Viewbox x:Name="vwbxZoom" Stretch="None">
<Viewbox.LayoutTransform>
<ScaleTransform ScaleX="{Binding ZoomLevel.Value}"
ScaleY="{Binding ZoomLevel.Value}" />
</Viewbox.LayoutTransform>
</ViewBox>
Here is a quick example. You may use any control as content of the Viewbox
<DockPanel>
<Slider x:Name="ZoomSlider" DockPanel.Dock="Bottom" Minimum="0.05" Maximum="2">
</Slider>
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<Viewbox Stretch="Uniform" VerticalAlignment="Center" HorizontalAlignment="Center">
<Border Width="2000" Height="2000">
<Border.Background>
<LinearGradientBrush StartPoint="0, 0.5" EndPoint="1, 0.5">
<GradientStop Color="Red" Offset="0.33"/>
<GradientStop Color="Green" Offset="0.66"/>
<GradientStop Color="Blue" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<Viewbox.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=ZoomSlider, Path=Value}" ScaleY="{Binding ElementName=ZoomSlider, Path=Value}"/>
</Viewbox.LayoutTransform>
</Viewbox>
</ScrollViewer>
</DockPanel>
In MainPage.xaml I have 2 canvas controls (bd1 and ball) that represent 2 layers.
<Canvas x:Name="ContentCanvas" Width="354" Height="669">
<Canvas.Background>
<RadialGradientBrush>
<GradientStop Color="#FF9D0A0A" Offset="0" />
<GradientStop Color="Black" Offset="1" />
</RadialGradientBrush>
</Canvas.Background>
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="bd1" Width="370" Height="480"
Clip="F1 M 0,0L 640,0L 640,480L 0,480L 0,0" MouseMove="Canvas_MouseMove" HorizontalAlignment="Left" VerticalAlignment="Top">
<Canvas.RenderTransform>
<TransformGroup>
<RotateTransform Angle="0" CenterX="0.5" CenterY="0.5" />
<TranslateTransform X="0" Y="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0"/>
</TransformGroup>
</Canvas.RenderTransform>
<Path....../>
........
</Canvas>
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Name="ball"
Width="54" Height="52.5" Clip="F1 M 0,0L 54,0L 54,52.5L 0,52.5L 0,0"
MouseMove="Canvas_MouseMove" HorizontalAlignment="Left" VerticalAlignment="Top">
<Canvas.RenderTransform>
<TransformGroup>
<RotateTransform Angle="0" CenterX="0.5" CenterY="0.5" />
<TranslateTransform X="0" Y="0" />
<ScaleTransform ScaleX="1" ScaleY="1" />
<SkewTransform AngleX="0" AngleY="0"/>
</TransformGroup>
</Canvas.RenderTransform>
<Canvas Width="640" Height="480.425" Canvas.Left="0" Canvas.Top="0">
<Ellipse x:Name="Ellipse" Width="54" Height="52.5" Canvas.Left="4.17233e-007" Canvas.Top="2.03252e-005" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FFFF0000">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0.0633299,0.762378" EndPoint="0.93667,0.237621">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FF000000" Offset="0"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Canvas>
</Canvas>
For that I created a class called Layer that has a Canvas property :
public class Layer
{
public Layer() { }
public Layer(Canvas canvas, Tipologie tip)
{
ThisCanvas = canvas; Tip = tip;
}
public string Name { get; set; }
private Canvas canv;
public Canvas ThisCanvas
{
get { return canv; }
set
{
canv = value;
if (value != null)
Name = value.GetValue(Canvas.NameProperty) as string;
}
}
}
In the MainPage class I have a global collection of Layer type. Initially I put in the collection 2 layers.
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
Layers[0] = new Layer(); Layers[0].ThisCanvas = GetTemplateChild("bd1") as Canvas;
Layers[1] = new Layer(); Layers[1].ThisCanvas = ball;
LayerSelector.ItemsSource = Layers;
}
Layer[] Layers = new Layer[2];
The problem is that bd1 and ball canvas controls are null . I also tried to put the code in the constructor of the page but it was the same problem.
I can't explain that.
Am I doing something wrong? Thanks in advance!
If you pass the Canvas in a constructor, then it will never be null unless you reassign it somewhere else.
public class Layer {
public Layer(Canvas canvas) {
this.canvas = canvas;
}
private Canvas canvas;
public Canvas ThisCanvas {
get { return canvas; }
set { canvas = value; }
}
...
}
...
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) {
Layers[0] = new Layer(GetTemplateChild("bd1") as Canvas);
Layers[1] = new Layer(ball);
LayerSelector.ItemsSource = Layers;
}
Layer[] Layers = new Layer[2];
OK, so I am pretty sure I'm on the right track with this small application, but let me know. The user enters in 3 of the 4 numbers into the 4 editable textboxes, and the missing number is calculated automatically. Picture of app here:
http://www.peauproductions.com/images/lens_app.PNG
I have looked at data binding, and I think I need to have the values able to globally change. I want the values to dynamically update/compute and not have to have a calculate button.
Once I get it working I need to implement a validation check to make sure a boolean is only entered (no text), and have a tooltip pop up saying to enter a number.
Getting the following ERROR right now:
"'Set property 'System.Windows.Controls.TextBox.Text' threw an exception.' Line number '56' and line position '51'."
MainWindow.xaml Code:
<Window x:Class="ConverterApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ConverterApp" Height="360" Width="280"
xmlns:c="clr-namespace:ConvertorApp;assembly=">
<Grid>
<!--Outer Box + Title-->
<TextBox Height="309" Width="248"
Text=" Lens Calculator"
IsReadOnly="True"
Margin="5,5,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
BorderThickness="2.0"
FontSize="16" FontFamily="Verdana" FontWeight="Bold">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Title Text-->
<TextBox Height="50" Width="230"
Text="Enter Image Width, Length and Either Distance or Lens Values Below"
IsReadOnly="True"
Margin="14,29,0,0"
TextWrapping="Wrap"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontSize="12" FontFamily="Verdana" FontStyle="Italic"
BorderThickness="0">
</TextBox>
<TextBox Height="20" Width="230"
Text="Must Be Same Units (in,ft,cm,mm)"
IsReadOnly="True"
Margin="14,59,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontSize="10" FontFamily="Verdana" FontStyle="Italic"
BorderThickness="0">
</TextBox>
<!--Distance-->
<TextBox Height="20" Width="105"
Text="Distance/Height:"
IsReadOnly="True"
Margin="15,80,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana"
BorderThickness="0">
</TextBox>
<TextBox x:Name="DistanceBox" Height="20" Width="50"
Text="{x:Static c:Variables.DistanceBox}"
Margin="125,80,0,0"
MaxLength="5"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Image Width-->
<TextBox Height="20" Width="90"
Text="Image Width:"
IsReadOnly="True"
Margin="15,105,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana"
BorderThickness="0">
</TextBox>
<TextBox x:Name="WidthBox" Height="20" Width="50"
Text="{x:Static c:Variables.WidthBox}"
Margin="125,105,0,0"
MaxLength="5"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Image Length-->
<TextBox Width="95"
Text="Image Length:"
IsReadOnly="True"
Margin="15,130,0,161" HorizontalAlignment="Left"
FontFamily="Verdana"
BorderThickness="0">
</TextBox>
<TextBox x:Name="LengthBox" Height="20" Width="50"
Text="{x:Static c:Variables.LengthBox}"
Margin="125,130,0,0"
MaxLength="5"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Lens Needed-->
<TextBox Height="20" Width="90"
Text="Lens (mm):"
IsReadOnly="True"
Margin="15,155,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana"
BorderThickness="0">
</TextBox>
<TextBox x:Name="LensNeeded" Height="20" Width="50"
Text="{x:Static c:Variables.LensNeeded}"
Margin="125,155,0,0"
MaxLength="4"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana">
<TextBox.BorderBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" >
<GradientStop Color="Black" Offset="0" />
</LinearGradientBrush>
</TextBox.BorderBrush>
</TextBox>
<!--Info-->
<TextBox Height="70" Width="230"
Text="The lens focal length value represents the estimated mm value for a 1/4 inch sensor (Playstation Eye). A lower mm will give a wider Field of View (FOV), and a higher value less FOV. "
IsReadOnly="True"
TextWrapping="Wrap"
Margin="15,180,0,0"
FontSize="11"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana" FontStyle="Italic"
BorderThickness="0">
</TextBox>
<TextBox Height="55" Width="230"
Text="It is not recommend you use a lens of less than 2.5mm focal length with image tracking software due to distortion."
IsReadOnly="True"
FontSize="11"
TextWrapping="Wrap"
Margin="15,253,0,0"
VerticalAlignment="Top"
HorizontalAlignment="Left"
FontFamily="Verdana" FontStyle="Italic"
BorderThickness="0">
</TextBox>
</Grid>
MainWindow.xaml.cs Code:
using System;
using System.Windows;
namespace ConvertorApp
{
public class Variables
{
public const double DistanceBox = 0;
public const double WidthBox = 0;
public const double LengthBox = 0;
public const double LensNeeded = 0;
public const double WidthBased = 0;
public const double LengthBased = 0;
public void Calc()
{
double WidthBased = 2.952*(DistanceBox/WidthBox);
double LengthBased = 3.984*(DistanceBox/LengthBox);
if (WidthBased < LengthBased)
{
double LensNeeded = WidthBased;
}else{
double LensNeeded = LengthBased;
}
}
}
}
If you can think of an easier, or more correct way to go about what I'm trying to do, please let me know (I just started learning this WPF/C# stuff). Thanks
UPDATE:
Here is the back code showing suggested changes from below:
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 ConverterApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Variables();
}
}
public class Variables : INotifyPropertyChanged
{
// Declare the PropertyChanged event.
public event PropertyChangedEventHandler PropertyChanged;
private double m_distanceBox;
public double DistanceBox
{
get { return m_distanceBox; }
set
{
m_distanceBox = value;
// modify calc to read the text values
Calc();
// Call NotifyPropertyChanged when the source property
// is updated.
NotifyPropertyChanged("DistanceBox");
}
}
private double m_widthBox;
public double WidthBox
{
get { return m_widthBox; }
set
{
m_widthBox = value;
// modify calc to read the text values
Calc();
// Call NotifyPropertyChanged when the source property
// is updated.
NotifyPropertyChanged("WidthBox");
}
}
private double m_lengthBox;
public double LengthBox
{
get { return m_lengthBox; }
set
{
m_lengthBox = value;
// modify calc to read the text values
Calc();
// Call NotifyPropertyChanged when the source property
// is updated.
NotifyPropertyChanged("LengthBox");
}
}
private double m_lensBox;
public double LensNeeded
{
get { return m_lensBox; }
set
{
m_lensBox = value;
// modify calc to read the text values
Calc();
// Call NotifyPropertyChanged when the source property
// is updated.
NotifyPropertyChanged("LensNeeded");
}
}
public void Calc()
{
double WidthBased = 2.95 * (DistanceBox / WidthBox);
double LengthBased = 3.98 * (DistanceBox / LengthBox);
if (WidthBased < LengthBased)
{
LensNeeded = Math.Round(WidthBased,2);
}else{
LensNeeded = Math.Round(LengthBased,2);
}
}
// NotifyPropertyChanged will raise the PropertyChanged event,
// passing the source property that is being updated.
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}
}
**ERROR I'm now getting is the StackOverflowException on the get {} inside the double functions. Any ideas?
The exception is thrown because the line
Text="{x:Static c:Variables.DistanceBox}"
is effectively something like
textBox.Text = Variables.DistanceBox;
This wouldn't compile in C#. In XAML, it throws exception. What you should do instead is create properties from your fields:
public double DistanceBox { get; set; }
And set Variables as DataContext of your window, by adding
DataContext = new Variables();
to the constructor of your window (or handler of the Loaded event).
You then use bindings in your XAML (which uses a converter to make strings out of doubles):
Text="{Binding DistanceBox}"
To call Calc() whenever a value changes, you can change the property to
private double m_distanceBox;
public double DistanceBox
{
get { return m_distanceBox; }
set
{
m_distanceBox = value;
Calc();
}
}
To make sure changes in Variables are reflected in the text boxes, you should implement the INotifyPropertyChanged interface.
EDIT: C# code of MainWindow:
public partial class MainWindow
{
public MainWindw()
{
InitializeComponent();
DataContext = new Variables();
}
}
Do you want to set text ? In wpf you need to use invoke method insted of of setting direct text property.
Your make mistake in setting text values:
YourTextBox.Text=YourValue;
in your case:
LensNeeded.Text = WidthBased.ToString();
You should use data binding for your text boxes.
Modify your Variables class to exposes the 4 values as string properties (you cannot databind to fields, only properties):
public class Variables
{
// code as in your example
public string LensValueNeeded
{
get { return LensNeeded.ToString(); }
set { Calc(); } // modify calc to read the text values
}
/// same for the other 3 values
}
Make sure that you modify your Calc method to read the current values from the TextBox as the data binding is setup to be two-way. You will need to convert the string values back to a double using the double.Parse() method:
double d = double.Parse(stringValue);
Set the DataContext of your Grid to an instance of your Variables class
Bind the text of your TextBox to the string property:
Text = {Binding LensNeededValue}