AutoScaleDimensions set to other value different from (6F, 13F) is not working on other computer with different screen resolutions - winforms

I have a System.Windows.Forms.UserControl and I have observed that if the design-time AutoScaleDimensions is set to (6F, 13F) from InitializeComponent (this is auto-generated automatically by Visual Studio Designer) in MyUserControl.Designer.cs then it works on other computer with different screen resolutions but if I change it to other values different from (6F, 13F), for example, (12F, 25F), then when changing to other computers with other screen resolutions, it does not work.
So, why it is happening? Could anybody explain me that?
MyUserControl.Designer.cs:
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.ElementHostFormControl = new System.Windows.Forms.Integration.ElementHost();
this.WPFUserControl = new WPFUserControl ();
this.SuspendLayout();
//
// ElementHostFormControl
//
this.ElementHostFormControl.Dock = System.Windows.Forms.DockStyle.Fill;
this.ElementHostFormControl.Location = new System.Drawing.Point(0, 0);
this.ElementHostFormControl.Name = "ElementHostFormControl";
this.ElementHostFormControl.Size = new System.Drawing.Size(500, 40);
this.ElementHostFormControl.TabIndex = 0;
this.ElementHostFormControl.Child = this.WPFUserControl;
//
// MyUserControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.ElementHostFormControl);
this.Name = "MyUserControl";
this.ResumeLayout(false);
}

Related

Creating System.Windows.Controls and adding Two Way Binding of a Field to a UserControle in WPF

What i want to do is the Following
Create an UserControle like this:
public partial class MyUserControle : UserControl
with a Wrappanel inside to add Controls and stuff to
<WrapPanel Margin="0,0,0,41" Name="wrapPanel1" />
this class has 2 Buttons to Cancel or Apply the Settings in the Window.
The window later gets open like this
Window w = new Window();
w.SizeToContent = System.Windows.SizeToContent.WidthAndHeight;
w.Content = myClass.getmyUserControle();
bool? t = w.ShowDialog();
Where myClass is a special Class that creates the UserControle and adds some stuff it wants to be changed in the WrapPanel
Now in myClass say i have a simple Point
System.Drawing.Point myPoint = new Point(10,15);
and getmyUserControle() looks like
public MyUserControle getmyUserControle(){
MyUserControle UC = new MyUserControle();
WPF.TextBox X1 = new WPF.TextBox();
System.Windows.Data.Binding BindingX = new System.Windows.Data.Binding("X");
BindingX.Source = myPoint;
BindingX.Mode = System.Windows.Data.BindingMode.TwoWay;
X1.SetBinding(WPF.TextBox.TextProperty, BindingX);
UC.addhere.Add(X1);
return UC;
}
The Textbox is filled properly but the changes dont change the source. How can i Fix this?
edit:
I can add a
private MyUserControle myUCsave = null;
to the class and set the
myUCsave = UC;
at the end of getmyUserControle() and check at the start
myUCsave != null return myUCsave;
that fixes the "save" of the textbox, but the underlying myPoint doesnt change.
Edit: Maybe there is a more simple Case: i create a simple Form and add this to the MainWindow via constructor
public partial class MainWindow : Window
public MainWindow()
{
InitializeComponent();
TextBox X1 = new TextBox();
TextBox Y1 = new TextBox();
X1.Margin = new Thickness(0, 0, 20, 20);
Y1.Margin = new Thickness(0, 0, 100, 100);
X1.Width = 100;
Y1.Width = 100;
X1.Height = 200;
Y1.Height = 200;
System.Windows.Data.Binding BindingX = new System.Windows.Data.Binding("X");
System.Windows.Data.Binding BindingY = new System.Windows.Data.Binding("X");
BindingX.Mode = System.Windows.Data.BindingMode.TwoWay;
BindingY.Mode = System.Windows.Data.BindingMode.TwoWay;
BindingX.Source = myPoint;
BindingY.Source = myPoint;
X1.SetBinding(TextBox.TextProperty, BindingX);
Y1.SetBinding(TextBox.TextProperty, BindingY);
this.MainGrid.Children.Add(Y1);
this.MainGrid.Children.Add(X1);
}
Point myPoint = new Point(100, 200);
This Should Create Two TextBoxes X1,Y1 that are Linked to the same source (myPoint.X)? But when i change one thing the other textbox doesn't change neither does the source.

GMap.NET - placing GMapControl in UserControl and then UserControl on Form yields MissingMethodException

I am trying to build a USerControl that contains a GMapControl. When I place the GMapControl directly on the Form, then it works as expected. If I however place the GMapControl on a UserControl, and then add that UserControl to the Form, I get errors.
For example:
My UserControl, Map.cs:
public Map()
{
InitializeComponent();
gMapControl1.MapProvider = GMapProviders.OpenStreetMap;
gMapControl1.Position = new PointLatLng(54.6961334816182, 25.2985095977783);
gMapControl1.MinZoom = 1;
gMapControl1.MaxZoom = 24;
gMapControl1.Zoom = 9;
top = new GMapOverlay("1");
objects = new GMapOverlay("objects");
routes = new GMapOverlay("routes");
polygons = new GMapOverlay("polygons");
gMapControl1.Overlays.Add(routes);
gMapControl1.Overlays.Add(polygons);
gMapControl1.Overlays.Add(objects);
gMapControl1.Overlays.Add(top);
gMapControl1.OnMarkerClick += new MarkerClick(gMapControl1_OnMarkerClick);
gMapControl1.OnPolygonClick += new PolygonClick(gMapControl1_OnPolygonClick);
}
Then I add this UserControl to my Form by dragging it on there. Then I get an Exception:
Failed to create component 'Map'. The error message follows:
'System.MissingMethodException: Method not found: 'Void
GMap.NET.WindowsForms.GMapControl.set_MapProvider(GMap.NET,
MapProviders.GMapProvider)'. at OpenStreetMapTest.Map..ctor()'
If I have the same code that I have in the UserControl Map inside a Form, then no errors. Also, the set_MapProvider exists and works if I don't put the GMapControl inside a UserControl.
Any ideas?
Decompile the code and see what the Map construtor is doing. Maybe it's locating some method by reflection. Can't think why else you'd get a MissingMethodException dependong on where the control is sitting.
On DesignMode suggestion, that property just flat out doesn't work for nested user controls which is really frustrating. However, you can use the following work around (this property would be in a UserControlBase class from which you would inherit)
Simply check IsDesignerHosted instead of IsDesignMode.
/// <summary>
/// Indicates if the code is being run in the context of the designer
/// </summary>
/// <remarks>
/// <see cref="Component.DesignMode"/> always returns false for nested controls. This is one
/// of the suggested work arounds here: http://stackoverflow.com/questions/34664/designmode-with-controls
/// </remarks>
public bool IsDesignerHosted
{
get
{
Control ctrl = this;
while (ctrl != null)
{
if ((ctrl.Site != null) && ctrl.Site.DesignMode)
return true;
ctrl = ctrl.Parent;
}
return false;
}
}
you should wrap everything inside the if ( !DesignMode )
eg.
Map()
{
InitializeComponent();
if ( !DesignMode )
{
gMapControl1.MapProvider = GMapProviders.OpenStreetMap;
gMapControl1.Position = new PointLatLng(54.6961334816182, 25.2985095977783);
gMapControl1.MinZoom = 1;
gMapControl1.MaxZoom = 24;
gMapControl1.Zoom = 9;
top = new GMapOverlay("1");
objects = new GMapOverlay("objects");
routes = new GMapOverlay("routes");
polygons = new GMapOverlay("polygons");
gMapControl1.Overlays.Add(routes);
gMapControl1.Overlays.Add(polygons);
gMapControl1.Overlays.Add(objects);
gMapControl1.Overlays.Add(top);
gMapControl1.OnMarkerClick += new MarkerClick(gMapControl1_OnMarkerClick);
gMapControl1.OnPolygonClick += new PolygonClick(gMapControl1_OnPolygonClick);
}
}

Silverlight 4 chart created at runtime won't show data

Using the Silverlight 4 toolkit chart control, I am trying to create a chart 100% at runtime with no evidence of it anywhere in the XAML. To do so, I create the blank chart when the page loads:
Chart TrendChart = new Chart();
TrendChart.Name = "TrendChart";
TrendChart.Title = "Call History";
TrendChart.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Stretch;
TrendChart.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
TrendChart.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
TrendChart.VerticalContentAlignment = System.Windows.VerticalAlignment.Stretch;
GridPanel.Children.Add(TrendChart);
After the user clicks on a button to retrieve data, a List is created of this custom class:
private class PhoneTrendDataPoint
{
public string XValue { get; set; }
public double YValue { get; set; }
}
I use that List, called CurrentCallTrends, as an ItemsSource for my chart.
// Update the chart with the received data
Chart TrendChart = (Chart)this.FindName("TrendChart");
// Wipe out previous chart data
TrendChart.Series.Clear();
// set the data
ColumnSeries columnSeries = new ColumnSeries();
columnSeries.Name = "Current Call Volume";
columnSeries.ItemsSource = CurrentCallTrends;
//columnSeries.SetBinding(ColumnSeries.ItemsSourceProperty, new Binding("CurrentCallTrends"));
columnSeries.DependentValueBinding = new Binding("XValue");
columnSeries.IndependentValueBinding = new Binding("YValue");
TrendChart.Series.Add(columnSeries);
The problem is that I get a runtime error where it prompts me to open a debugger regarding an object reference not set to an instance of an object. If I comment the line to .SetBinding then the ItemsSource vanishes and no data shows up, but at least there is no runtime error.
What am I missing?
After additional Googling, I made some modifications that seem to work but don't strike me as the best way to go about doing this. Data now shows up, but I will not accept this as the answer unless there is no better method:
// Update the chart with the received data
Chart TrendChart = (Chart)this.FindName("TrendChart");
// Wipe out previous chart data
TrendChart.Series.Clear();
// test data
KeyValuePair<string, double>[] CurrentCallData = new KeyValuePair<string, double>[CurrentCallTrends.Count];
for (int i = 0; i < CurrentCallTrends.Count; i++)
{
CurrentCallData[i] = new KeyValuePair<string, double>(CurrentCallTrends[i].XValue, CurrentCallTrends[i].YValue);
}
// set the data
ColumnSeries columnSeries = new ColumnSeries();
columnSeries.Name = "CurrentCallVolume";
columnSeries.Title = "Current Call Volume";
columnSeries.SetBinding(ColumnSeries.ItemsSourceProperty, new Binding());
//columnSeries.ItemsSource = CurrentCallTrends;
columnSeries.ItemsSource = CurrentCallData;
columnSeries.DependentValueBinding = new Binding("Value");
columnSeries.IndependentValueBinding = new Binding("Key");
TrendChart.Series.Add(columnSeries);
//this.DataContext = CurrentCallTrends;

Unable to set a property after its animation in WPF

I used this code to animation my window:
winLogin login = new winLogin();
login.Owner = this;
login.Show();
DoubleAnimation da = new DoubleAnimation();
da.From = 0;
da.To = this.Left + ((this.Width - login.Width) / 2);
da.AutoReverse = false;
da.Duration = new Duration(TimeSpan.FromSeconds(0.1));
login.BeginAnimation(Window.LeftProperty, da);
Problem is that whenever i set the Left property of this window(after the animation), it goes crazy.
I used this code to align the child windows to be always on the center but the Left property of the windows on which i used an animation cannot be properly changed.
private void Window_LocationChanged(object sender, EventArgs e)
{
foreach (Window win in this.OwnedWindows)
{
win.Top = this.Top + ((this.Height - win.Height) / 2);
win.Left = this.Left + ((this.Width - win.Width) / 2);
}
}
First of all, when you set an animation you should always remove the potential previous animation of that property:
login.BeginAnimation(Window.LeftProperty, null);
login.BeginAnimation(Window.LeftProperty, da);
If you don't so this you will get a memory leak and probably some other undesired behavior.
Also due to the DependencyProperty precedence you can not set a value on a DependecyProperty that has an active animation, wich is the case in your animation because its FillBehavior is set to HoldEnd (the default). Again you would have to remove the animation first.

How would I make a control that flashes/fades on a mouse click? (Windows)

When a user clicks in certain places in my control, I want to change the color of some rows and columns in my grid, then fade it back to the normal color, within say 500ms or so. I haven't decided whether to use Winforms or WPF yet, so advice in either of those technologies would work. Thank you.
Edit: I understand I could do this by just calling Paint in a loop within the click event, properly setting the drawing parameters. However I believe that would block the UI, and I would like to be more responsive than that.
WPF has very good support for animations. Animations are supported from both xaml and code behind, so you should be able to achieve any look that you are going for.
The MSDN Animation Overview for WPF looks to have a lot of good information for getting you started.
Here is one way you could handle the fade:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsApplication1
{
public class FadeForm : Form
{
private Timer fadeTimer;
private Panel fadePanel;
private Button fadeButton;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose( bool disposing )
{
if ( disposing && ( components != null ) )
{
components.Dispose();
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.fadePanel = new System.Windows.Forms.Panel();
this.fadeButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// fadePanel
//
this.fadePanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fadePanel.Location = new System.Drawing.Point( 4, 8 );
this.fadePanel.Name = "fadePanel";
this.fadePanel.Size = new System.Drawing.Size( 276, 104 );
this.fadePanel.TabIndex = 0;
//
// fadeButton
//
this.fadeButton.Location = new System.Drawing.Point( 104, 116 );
this.fadeButton.Name = "fadeButton";
this.fadeButton.Size = new System.Drawing.Size( 75, 23 );
this.fadeButton.TabIndex = 1;
this.fadeButton.Text = "Fade";
this.fadeButton.UseVisualStyleBackColor = true;
this.fadeButton.Click += new System.EventHandler( this.HandleFadeButtonClick );
//
// FadeForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size( 284, 142 );
this.Controls.Add( this.fadeButton );
this.Controls.Add( this.fadePanel );
this.Name = "FadeForm";
this.Text = "Fade Form";
this.ResumeLayout( false );
}
#endregion
public FadeForm()
{
InitializeComponent();
this.fadeTimer = new Timer();
}
private void HandleFadeButtonClick( object sender, EventArgs e )
{
this.fadeTimer.Tick += new EventHandler( HandleFadeTimerTick );
this.fadePanel.BackColor = Color.Red;
this.fadeTimer.Interval = 100;
this.fadeTimer.Start();
}
void HandleFadeTimerTick( object sender, EventArgs e )
{
Color panelColor = this.fadePanel.BackColor;
if ( panelColor.A > 0 )
{
this.fadePanel.BackColor =
Color.FromArgb(
Math.Max( panelColor.A - 20, 0 ),
panelColor.R, panelColor.G, panelColor.B );
}
else
{
this.fadeTimer.Stop();
}
}
}
}
Unfortunately, this approach doesn't seem to work with rows in a DataGridView. I don't know the reason, but the color doesn't show at all if the alpha component of the color isn't 255. If you can find a way around that, this code might help.
At its simplest, a fade effect like this just requires a timer of some sort that gradates the color back towards normal with each tick. The faster the time, the more discrete colors you will display from start to finish, and the smoother the overall effect will be (WPF may have something built-in to do this).
You definitely do not want to repaint in a loop. As you pointed out this will block the UI, and also you would not be able to control how long the loop takes (different machines will render the same number of steps from highlight color to normal in different lengths of time).

Resources