Puzzle. WPF host in winform - bug with string containing "_" - c#

Hosting WPF in winform is explained here Walkthrough: Hosting a WPF Composite Control in Windows Forms. I explain the problem in the most simple way: just create a winform project. Then I create another project WPF User Control Library. On User control library I add one button and name it button1. Then in xaml.cs file i create one public function which looks like this:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public void SetText(string text)
{
button1.Content = text;
}
}
I add that project as a reference in winform so I can add control to my winform. In winform I add one button and create button onClick event. The code looks like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
wpfButton.SetText("asd 12_2_a_s");
}
}
And now the party begins. I compile the project and the final looks like that:
So if I click on left button, on right button there should show string looks like this: "asd 12_2_a_s". But, what is happening is always first "_" is missing. That I get this:
The primitive solution that problem is just to write doubles "__" wpfButton.SetText("asd 12__2__a__s");
And that works. But my question is: Is this is actual bug or I missing something?

The underscore in the text/content of a control is a character used to indicate the access key. You can escape it by using a double underscore __
"t__est"
Haven't tested this, but you also could use the # sign. #"t_est" will output t_est
EDIT: # Doesn't work for setting Text/Content Properties.

Related

User control inheriting from GroupBox cant be edited in design mode

I want to extend a GroupBox by adding a button on the caption. If I do this
public partial class MyInheritedGroupBox : GroupBox
{
public MyInheritedGroupBox()
{
InitializeComponent();
}
}
Works at runtime, but the control itself can't be edited anymore in the designer. Double clicking on the control now shows this
Is there some magic attributes so it shows up in the designer?
I'm trying to avoid inheriting from UserControl because it then introduces other complexities like this
Not sure what you want, there are 2 things that could be possible.
1, After dropping your control on a form you are not able to edit it using the designer and the object inspector. If that is the case you can solve it like this :
[Designer(typeof(ControlDesigner))] //without this you cannot change properties in the designer
public partial class MyInheritedGroupBox : GroupBox
{
public MyInheritedGroupBox()
{
InitializeComponent();
}
}
2, You want to build your control visually by double clicking on the class in the solution explorer.
If that is the case than you are out of luck.
You will need to create a UserControl for that.

How to show output in webapp directlt at form1 C#

I want to print values at bottom of Form1 directly. It is a web app so if I
write Console.WriteLine("Something"); it doesn't make sense or doesn't print out any thing at Form1. How can I print in Form1 directly?
Here's a pictorial sequence for printing the word "Something" on a web form (on your browser):
Right-click on the blue highlighted WebApplication2.
A webform will appear:
Press F7 key to go to the webform code page.
Then look at your resulting browser page.
UPDATE:
Oh, so you want to write to a winform instead of a webform. Use this code:
using System;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void label1_Click(object sender, EventArgs e)
{
label1.Text = "Something";
}
}
}
Then,
Put your mouse on label1, right-click, choose "View Designer".
In the properties box, go to the "Text" property.
To the right of the property, type "Click here" to replace "Label1".
Hit return.
Then run it.
I assume you are using a ASP.NET Web Forms and want to add controls directly to the HTML via code behind.
Look into UserControls for a more proper way moving forward. https://msdn.microsoft.com/en-us/library/y6wb1a0e.aspx
But to answer your question directly, the quick and dirty is below.
Within the aspx file create a PlaceHolder
<asp:PlaceHolder ID="phMain" runat="server"></asp:PlaceHolder>
In the code behind you can add HTML directly to the PlaceHolder
phMain.Controls.Add(new LiteralControl("<span>Hello!</span>"));
Update
I see you added a picture of a WinForm app after you said Web App. In that case you should try a ListView https://msdn.microsoft.com/en-us/library/system.windows.forms.listview(v=vs.110).aspx

How to change a control property (FlatStyle) in base form?

This might be kind of beginner question but I searched and didn't find any clear answer!
The main question is: How to inherit properties of a control (specially FlatStyle) from a base form which doesn't have that control in C#?
Details: I have Form1 inherited from baseForm. baseForm has a Panel and a Label control but no Button. In Form1 I added a button named Button1. How can I change the style of that Button through the baseFrom?
I don't want to create a custom control or redesign the button using rectangles or similar ways, but only change that property for all buttons in my application.
UPDATE: I want all of the buttons to be affected, whether they already exist or just added. Not matter in which -if any- container they are.
In baseForm, you could hook the ControlAdded event on the Panel where the Button is to be added, and style appropiately via code. This will work for every form inherited from baseForm.
For example (in baseForm)
public partial class BaseForm : Form
{
public BaseForm()
{
InitializeComponent();
// "myPanel" is the panel where the button will be added in inherited forms
myPanel.ControlAdded += myPanel_ControlAdded;
}
private void myPanel_ControlAdded(object sender, ControlEventArgs e)
{
var button = e.Control as Button;
if (button != null)
{
button.FlatStyle = FlatStyle.Flat;
button.ForeColor = Color.Red;
}
}
}
Just made a really quick test... it works even in design mode:
As an alternative, if you are going to use heavily styled buttons everywhere in your application, you may consider creating a custom control inheriting from Button, and assign the properties there, like:
public class FlatButton : System.Windows.Forms.Button
{
public FlatButton()
{
FlatStyle = FlatStyle.Flat;
}
}
After building, you will find it in the Toolbox (under "[Your Project's] components" tab), or you can cram it on your own control library (in a different solution) and add it permanently to the Toolbox in Visual Studio.
You would need to make use of Reflection
You can use a LINQ query to do this. This will query everything on the form that is type Button
var c = from controls in this.Controls.OfType<Button>()
select controls;
foreach(var control in c)
control.FlatStyle = FlatStyle.Flat;

Windows Forms - using public event to subscribe Form to a user control event

I have an issue when it comes working with events and/or delegates. I saw very similar questions but still the real implementation is not clear to me. So please when you answer be more specific so I can try and eventually understand how exactly creating/handling of public/custom events work by doing it in a code I know.
What I have is a User Control which is simply a text box and a button I need to change a record in a database using the value from the text box. I'm using this control for many forms so I need to know which entity exactly I'm using and be able to call it's own save method. Doing all that will be easier if I just can use the click event of the button from my User Control and then call the Save() method of the current form.
This is my User Control :
namespace UserControls.CommonControls
{
public delegate void ClickMe(string message);
public partial class ChangeCode : UserControl
{
public event ClickMe CustomControlClickMe;
public ChangeCode()
{
InitializeComponent();
}
private void btnChange_Click(object sender, EventArgs e)
{
if (CustomControlClickMe != null)
CustomControlClickMe("Hello");
//ToDo fill
//MessageBox.Show("To Do: Write the busieness logic.");
}
public void SetTextBoxMask(MaskedTextBox txtBox)
{
txtChange.Mask = txtBox.Mask;
}
}
}
I post it with the last attempt I made to try and implement what I need.
This is one of the form that need to use the Click event from the User Control and more specific the Constructor because if I understand right there is the place where I have to subscribe for the event :
public MaterialEdit()
{
InitializeComponent();
UserControls.CommonControls.ChangeCode. += new ClickMe(button2_Click);
}
UserControls.CommonControls.ChangeCode - this is how I reach my User Control it's named ChangeCode.
From what you pasted it is not clear that you added ChangeCode control to your form. To use the control and it's events and properties, first you must create new instance to it and add it to the form. This is done:
In designer, by dragging control from Toolbox to the form
In code editor, by invoking control constructor and adding new object to control collection
Only then can you handle event of that object. Let's say that you dropped ChangeCode control to a form, and that Visual Studio named it ChangeCode1. You attach a handled to CustomControlClickMe event like this:
ChangeCode1.CustomControlClickMe += new ClickMe(button2_Click);
Code you pasted (UserControls.CommonControls.ChangeCode. += new ClickMe(button2_Click);) is incorrect for several reasons:
Syntactically, left hand side expression ends with . which makes it incorrect assignment target (UserControls.CommonControls.ChangeCode.)
Event name is not provided, only the control name (you need to end left hand side of assignment with what you want to assign to - .CustomControlClickMe)
You are trying to attach handler to a class and not an object

How can I access the MainForm from within a class in a separate project?

I have two projects in this solution: ProjectA and ProjectB. ProjectA is the main start-up project, and has a reference to ProjectB.
ProjectA has a file called MainForm.cs, which contains a textbox and the main UI.
ProjectB has a class inside Shapes.cs, containing a particular structure we're using. Shapes.cs contains an event that is fired when the user changes some text for that object.
What I need to do is catch that text and set a textbox in MainForm.cs to that text. Is there a way we can do that? Basically I don't see any reference to the main form inside Shapes.cs. I would like to do something like this:
( Shape1.Parent as MainForm ).TextBox1.Text = Shape1.Name;
, assuming the user types a string that gets stored in Shape1.Name. I need to escalate it to the main form.
I have searched around for other questions, and the closest lead I found was Matt Hamsmith's answer on this question. But if it is a good approach I should follow, I do not know how to assign an event handler in the main form to an event in the separate class. I would appreciate any help.
Thanks.
If the form is made up child controls, it should be listening to events on those controls, rather than the controls trying to cast their parent as a particular type. Doing that means your control will only ever work on that Form. It breaks encapsulation.
Listen to an event like this:
public class MainForm : Form
{
Shape _shape1 = new Shape();
public MainForm()
{
InitializeComponent();
_shape.ShapeNameChanged += HandleShapeNameChanged;
}
public void HandleShapeNameChanged(object sender, ShapeChangeEventArgs e)
{
textBox1.Text = e.NewName;
}
}
public class Shape
{
public event EventHandler<ShapNameChangedEventArgs> ShapeNameChanged;
}
I've left it for you to:
Define the ShapeNameChangedEventArgs object to contain whatever state you want it to.
Invoke the event when something on your control changes.
Good luck!

Categories

Resources