Why selecting text in the TextBlock throws exception in WinRT - c#

The following code snippet throws a System Exception.
TextBlock selectionText = new TextBlock();
selectionText.IsTextSelectionEnabled = true;
selectionText.Text = "Hello world";
selectionText.Foreground = new SolidColorBrush(global::Windows.UI.Color.FromArgb(255, 255, 0, 0));
selectionText.SelectAll();
What is wrong in my code?
Thanks in advance

You should make sure selectionText is displayed before calling SelectAll() on it, i.e. you should add it to a panel inside your current page:
TextBlock selectionText = new TextBlock();
selectionText.IsTextSelectionEnabled = true;
selectionText.Text = "Hello world";
selectionText.Foreground = new SolidColorBrush(global::Windows.UI.Color.FromArgb(255, 255, 0, 0));
MainPanel.Children.Add(selectionText);
Dispatcher.RunAsync(CoreDispatcherPriority.Normal, selectionText.SelectAll);
Notice two changes:
The call to MainPanel.Children.Add() where MainPanel is the name of a panel control on your page.
selectionText.SelectAll() called via Dispatcher to make sure selectionText is actually added to the panel before the call executes.

My guess is the forgrund color
Color.FromArgb(255, 255, 0, 0)
The first number desides the level of "Alpha" which means transparancy. Windows RT may not be able to handel that.
Try this instead
Color.FromArgb(0, 255, 0, 0)

Related

Label not visible above ToolStrip

At runtime I add (and remove) several controls, as needed, to a main window which in Designer contains only a ToolStrip with some function buttons. In some cases I want to add an info label next to the toolStrip, but I cannot make it visible, ie. it is hidden below. The code for the label is straightforward
infoLabel = new Label();
infoLabel.AutoSize = true;
infoLabel.Location = new System.Drawing.Point(200, 10);
infoLabel.Size = new System.Drawing.Size(35, 13);
infoLabel.BackColor = System.Drawing.SystemColors.Control;
infoLabel.Font = new System.Drawing.Font("Arial", 13);
infoLabel.ForeColor = System.Drawing.Color.Black;
infoLabel.TabIndex = 1;
infoLabel.Text = "this is info";
infoLabel.BringToFront();
this.Controls.Add(infoLabel);
TabIndex and BringToFront I added as an act of desperation, it does not help. BTW the ToolStrip's TabIndex is 2, and its BackColor I changed to transparent.
However, when I placed a label over the ToolStrip in the Designer, it is visible (ie. on top). I analysed the code then but did not see anything different from what I am writing. What am I missing here?
I suggest calling infoLabel.BringToFront(); at the very end, at least after this.Controls.Add(infoLabel); you current code amended:
infoLabel = new Label();
...
infoLabel.Text = "this is info";
// First Add to this
this.Controls.Add(infoLabel);
// Only then we can make infoLabel be the topmost
// among all existing controls which are on this
infoLabel.BringToFront();
We create infoLabel, add it to this and finally make it topmost on this. To make code more readable I suggest something like this:
// Create a label on this
infoLabel = new Label() {
AutoSize = true,
Location = new System.Drawing.Point(200, 10),
Size = new System.Drawing.Size(35, 13),
BackColor = System.Drawing.SystemColors.Control,
Font = new System.Drawing.Font("Arial", 13),
ForeColor = System.Drawing.Color.Black,
TabIndex = 1,
Text = "this is info",
Parent = this // <- instead of this.Controls.Add(infoLabel);
};
// make infoLabel topmost among all controls on this
infoLabel.BringToFront();
Windows Forms controls do not have a property which you can use to set z-index of controls like one can do in CSS.
You'll need to call Parent.SetChildIndex(control, 0);. The control at the front of Controls collection is the topmost in z-order for a container control.

Error adding new TextBlock to Canvas in WPF

I want to add text to my canvas in WPF. The code runs until I want to add the TextBlock to the canvas as a child, giving me this:
"Specified element is already the logical child of another element. Disconnect it first."
Here is the relevant code:
private void txtbItemName_TextChanged(object sender, TextChangedEventArgs e)
{
TextBlock txtItemName = new TextBlock();
txtItemName.Text = txtbItemName.Text;
txtItemName.Margin = new Thickness(10, 10, 0, 0);
cnvImage.Children.Remove(txtItemName);
cnvImage.Children.Add(txtbItemName); //The error screen showed up when running this line
}
You have an error. You are trying to remove the new item and add existing one.
Here is a right code for you:
TextBlock txtItemName = new TextBlock();
txtItemName.Text = txtbItemName.Text;
txtItemName.Margin = new Thickness(10, 10, 0, 0);
cnvImage.Children.Remove(txtbItemName);
cnvImage.Children.Add(txtItemName);
It seems that your txtbItemName is already a child of an element in your XAML i suppose (can't see your XAML). because you have already created this element in your xaml it won't let you add it to the canvas.
I found it: I indeed tried to place an object that was already present. I accidentally placed an existing textBOX (txtb) instead of a textBLOCK (txt). Thanks for the help though!

Use variable value as x:Name

I have a button called myBtn. in XAML: ( <Button x:Name="myBtn" ... )
I have also a variable, which value is myBtn
Now, I need change this button's color:
public string buttonName = "myBtn";
private void method ()
{
this.buttonName.Background = new SolidColorBrush(Color.FromRgb(255, 0, 255));
}
This gives error:
string does not contain definition for Background
What is right syntax to do this?
Try this:
public Button buttonName;
private void method ()
{
buttonName = this.FindName("myBtn") as Button;
buttonName.Background = new SolidColorBrush(Color.FromRgb(255, 0, 255));
}
myBtn.Background = new SolidColorBrush(Color.FromRgb(255, 0, 255));
Once you give the control the x:Name attribute, you can refer to it directly from code behind without doing anything else.
You can access the background color of a named XAML button by using
myBtn.Background = new SolidColorBrush(Color.FromRgb(255, 0, 255));
The name you specify becomes a Button object for the code-behind in the application you are building.

c# winforms dock fill tree-view make it disappear

I have a winforms application. In my application I have a user control which I loaded programmatically.
Inside this user-control I have tree view that also will be loaded with items programmatically. My problem is that I want to make my tree-view take the whole size of its parent.
What I have tried
I set the user-control Dock property to DockStyle.Fill to make it take the size of its parent.
I have done the same for the tree-view Dock property; set it to DockStyle.Fill.
What I get
The user-control takes the full size as expected but the tree-view looks like it is hidden. I checked the height, and I noticed it's 0. When I tried to change the height while it has DockStyle.Fill I can't, it changes back to 0.
Any ideas?
Update
The auto generated code for the tree-view:
private void InitializeComponent()
{
this.btnAddServer = new System.Windows.Forms.Button();
this.pnlServersContainer = new System.Windows.Forms.FlowLayoutPanel();
this.treeViewServers = new System.Windows.Forms.TreeView();
this.pnlServersContainer.SuspendLayout();
this.SuspendLayout();
//
// btnAddServer
//
this.btnAddServer.Location = new System.Drawing.Point(89, 478);
this.btnAddServer.Name = "btnAddServer";
this.btnAddServer.Size = new System.Drawing.Size(107, 23);
this.btnAddServer.TabIndex = 3;
this.btnAddServer.Text = "Add New Server";
this.btnAddServer.UseVisualStyleBackColor = true;
this.btnAddServer.Click += new System.EventHandler(this.btnAddServer_Click);
//
// pnlServersContainer
//
this.pnlServersContainer.AutoScroll = true;
this.pnlServersContainer.Controls.Add(this.treeViewServers);
this.pnlServersContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlServersContainer.Location = new System.Drawing.Point(0, 0);
this.pnlServersContainer.Name = "pnlServersContainer";
this.pnlServersContainer.Padding = new System.Windows.Forms.Padding(8, 20, 0, 0);
this.pnlServersContainer.Size = new System.Drawing.Size(318, 463);
this.pnlServersContainer.TabIndex = 2;
//
// treeViewServers
//
this.treeViewServers.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeViewServers.Location = new System.Drawing.Point(11, 23);
this.treeViewServers.Name = "treeViewServers";
this.treeViewServers.Size = new System.Drawing.Size(275, 0);
this.treeViewServers.TabIndex = 0;
this.treeViewServers.DoubleClick += new System.EventHandler(this.treeViewServers_DoubleClick);
//
// ucServersList
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Controls.Add(this.btnAddServer);
this.Controls.Add(this.pnlServersContainer);
this.Name = "ucServersList";
this.Padding = new System.Windows.Forms.Padding(0, 0, 0, 60);
this.Size = new System.Drawing.Size(318, 523);
this.Load += new System.EventHandler(this.ucServersList_Load);
this.pnlServersContainer.ResumeLayout(false);
this.ResumeLayout(false);
}
I recommend to open Document outline editor in Visual Studio.
This shows all controls in their hierarchical order as tree.
It lets you also drag & drop the controls to the right place.
Open it with View > Other windows > Document outline.
You may fix your problem when looking at the controls order.
I have figured it out. but still don't know why this happened!
my tree-view was inside FlowLayoutPanel not Panel. When i changed it to Panel everything goes fine. that's it!
The problem might be that you have added several items to the same parent control, and then when you fill the parent dock with one of them, the behaviour would not be what you expect.
Use a splitcontainer. And when you want to fill out the dock, make sure your control belongs to two differnt panels of a splitcontainer.
See this for an concrete example.
Is there any specific reason why you use FlowLayoutPanel?
It seems that the FlowLayoutPanel does not deal with any other than Dock.None.
I think you should use a simple Panel for this application, because it does not resize the contained controls - the Dock property behaves as expected.
Replacing the FlowLayoutPanel with a Panel will fix your problem.
This is a super old question... but since there are no accepted answers I’ll give it a go.
This happened to me when my Control was set to autosize. Either removing autosize or specifying a minimum height could solve this issue.

Common class for WPF Containers (Canvas, Grid, etc)

I am creating a method that is invoked by a button. The method then adds a canvas to the button's parent container control. So, e.g., the button is on a grid. Then the method creates a canvas that is shown just below the button. But I have 2 issues:
How can I get a reference to the button's parent container?
Is there a class for container controls? I don't care if the button is in a grid, a canvas, a Stackpanel, etc. So I am looking for an interface that all types of contianers implement or a class that they inherit.
The second aspect is more important as I could pass a reference to the container manually.
EDIT:
It should look like this (minus the colors, those are only to show the different elements.
The red canvas is supposed to pop up to handle a confirmation. Maybe even with a nice animation. My idea was to create a class that can be invoked similar to this:
MyPopup popup = new MyPopup("Are you sure?", "Yes", "No", delegateFirstButton, delegateSecondButton);
popup.Show();
My code so far is not yet a class but only a method. The text parts are hard coded for the moment. The marked line needs to be more flexible and is the reason for my question.
public void ShowPopup(Control senderControl)
{
//I need to have a parameter that accepts all containers instead of this line:
this.myGrid.Children.Add(popup);
Border border = new Border();
popup.Children.Add(border);
border.Margin = new Thickness() { Top = 10 };
border.Child= text;
text.Text = "Are you sure?";
text.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
popup.SizeChanged += delegate { border.Width = popup.ActualWidth; };
popup.Children.Add(btn1);
btn1.Content = "Yes";
btn1.Height = 22;
btn1.Padding = new Thickness(10, 0, 10, 0);
btn1.Margin = new Thickness() { Left = 15, Top = 35 };
popup.Children.Add(btn2);
btn2.Content = "No";
btn2.Height = 22;
btn2.Padding = new Thickness(10, 0, 10, 0);
btn1.SizeChanged += delegate { btn2.Margin = new Thickness() { Left = 30 + btn1.ActualWidth, Top = 35 }; };
popup.Height = 70;
btn2.SizeChanged += delegate
{
popup.Width = 45 + btn1.ActualWidth + btn2.ActualWidth;
updatePositions(senderControl);
};
popup.Background = Brushes.Red;
popup.VerticalAlignment = System.Windows.VerticalAlignment.Top;
popup.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
}
public void updatePositions(Control senderControl)
{
Point location = senderControl.TranslatePoint(new Point(0, 0), this.myGrid);
popup.Margin = new Thickness()
{
Left = location.X + (senderControl.ActualWidth / 2) - (popup.Width / 2),
Top = location.Y + senderControl.ActualHeight + 15
};
}
Sounds like you're choosing the hard way to do that.
If you need a popup, then use a Popup.
Otherwise, if for whatever reasons you don't want to use that, You'd better place a grid somewhere near the root of your XAML, and ALWAYS use that as a container:
<Window>
<Grid x:Name="MainUI"/>
<Grid x:Name="PopupContainer"/>
</Window>
Otherwise, you'll almost invariably encounter Z-Index problems (if you follow your current approach).
Also, it's a really bad idea to create all that UI stuff in code. Either encapsulate your Yes/No dialog in a UserControl or create a proper Template for that.
As I said before, avoid at all costs creating/manipulating UI elements in code, as it creates a lot of maintainability issues.

Categories