How can I send to back an element in wpf? - c#

I want to send an element behind all of the elements.
I tried to use Z-Index but it did not work because I need to send it behind all of the elements and I don't know how many are they(elements can increase by user);
pls help.

I'm assuming that you want to do this in code, that you want to place a new element (in my example, a Label) "behind".
The way to do this is to replace the current Content of your control/window with a Grid, and then place your element in it together with the current content.
void PlaceLabelBehindEverything()
{
var newLabel = new Label() { Content = "My Label that is behind everything" };
var currentContent = this.Content; // assuming this method is in the control/window
var grid = new Grid();
this.Content = grid;
grid.Children.Add(newLabel);
grid.Children.Add(currentContent);
{

Related

DesiredSize of a button and radio button in UWP XAML

I need to measure the DesiredSize or ActualHeight/Width of a button (and radio button) without actually putting it onto the visual tree but I keep getting back non-sense values. This same approach works when measuring other controls such as TextBlock.
var button = new Button
{
Content = "Hello World",
FontSize = 15
};
button.Measure(new Size(maxWidth, double.PositiveInfinity));
var height = button.DesiredSize.Height;
var width = button.DesiredSize.Width
I'm getting back 21px for height and 0px for width. Any idea why I'm getting 0 back for width?
I need to measure the DesiredSize or ActualHeight/Width of a button (and radio button) without actually putting it onto the visual tree but I keep getting back non-sense values.
If you assign a string value to Button.Content, the value will be assigned to the inside TextBlock through Binding in runtime, which happens after the Button.Measure (You can see this by adding the button to the page and check the LiveProperty Explorer):
So you get the wrong desired size.
As a workaround, you can create a TextBlock and assign this TextBlock to the button:
var tbContent = new TextBlock()
{
Text = "Hello World",
FontSize=15
};
var button = new Button
{
Content = tbContent,
};
var h= button.DesiredSize.Height;
button.Measure(new Size(200, double.PositiveInfinity));
var height = button.DesiredSize.Height;
var width = button.DesiredSize.Width;
Then you will get the correct Size of this button.
I'm guessing that this isn't possible. You're measuring the button before it has loaded its template.
I can only suggest doing something like this:
var but = new Button();
but.Content = "Hello";
var popup = new Popup();
popup.Child = but;
popup.IsOpen = true;
popup.Visibility = Visibility.Collapsed;
but.Loaded += (s, e) =>
{
System.Diagnostics.Debug.WriteLine(but.RenderSize);
popup.IsOpen = false;
};
But it's kind of hacky, and the button won't load until some later time, making this whole process asynchronous which might be difficult to manage.

How to show more that one image in the radtreeview item (wpf - telerik )

I am adding image to the radtreeviewitem from resources programatically using the below code.
"/myAssembley;component/Resources/image1.png"
and the image is displaying successfully. Now i need to add another image which needs to be displayed next to the first image in the radtreeviewitem.
how to achieve it.?
Like the below image i need my treeviewitem to display a folder icon and a red square icon in a single treeview item.
If you do not have data binding and you are using RadTreeViewItems directly you can add the additional image in the Header of the item. For example:
var stackPanel = new StackPanel() { Orientation = System.Windows.Controls.Orientation.Horizontal };
var image1 = new Image() { Source = image1Path };
var image2 = new Image() { Source = image2Path };
var textBlock = new TextBlock() { Text = itemHeader };
stackPanel.Children.Add(image1);
stackPanel.Children.Add(image2);
stackPanel.Children.Add(textBlock);
var treeViewItem = new RadTreeViewItem()
{
Header = stackPanel,
};
It Works.
The proper way would be to create a DataTemplate with a grid or horizontal stackpanel. Put two images inside and in your model two Image Sources that you can bind too. Telerik doesn't have the best track record using the MVVM pattern, but the TreeView control is pretty decent with binding. If you need help with the model and the datatemplate, post some of your code here and we can work on it.

Adding Space into a StackPanel full of Textboxes

I am new at C# & XAML development. I created a metro app with several textboxes. These textboxes are loaded in XAML data through a StackPanel in C# code, it has to be hardcoded. The problem is, I have no clue how I can add some empty spaces between every single textbox. Has anyone an idea?
The Code :
private void AddLastestCreatedField()
{
// Load the last created Field From DB
DBFunction.FieldTypes latestField;
DBFunction.Class1 myDBClass = new DBFunction.Class1();
latestField = myDBClass.GetLastestField();
// add new textbox and put it on the screen
var dragTranslation = new TranslateTransform();
//Generate the TextBox
TextBox fieldTextBox = new TextBox();
fieldTextBox.Name = "fieldTextBox_" + latestField.ID.ToString();
fieldTextBox.FontSize = 15;
fieldTextBox.Background.Opacity = 0.8;
ToolTip toolTip = new ToolTip();
toolTip.Content = latestField.Description;
ToolTipService.SetToolTip(fieldTextBox, toolTip);
fieldTextBox.IsReadOnly = true;
// Add Drag and Drop Handler for TextBox
fieldTextBox.ManipulationMode = ManipulationModes.All;
fieldTextBox.ManipulationDelta += fieldTextBox_ManipulationDelta;
fieldTextBox.ManipulationCompleted += fieldTextBox_ManipulationCompleted;
fieldTextBox.RenderTransform = dragTranslation;
dragTranslationDict.Add(fieldTextBox.Name, dragTranslation);
fieldTextBox.RenderTransform = dragTranslation;
// Add TextBox to a List to control later
TxtBoxList.Add(fieldTextBox);
// Generate TextBlock for each TextBlock
TextBlock fieldTextBlock = new TextBlock();
// fieldTextBlock.Name = "fieldTextBlock_" + cnt.ToString();
fieldTextBlock.TextAlignment = TextAlignment.Right;
fieldTextBlock.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Right;
fieldTextBlock.Name = "fieldTextBlock_" + latestField.ID.ToString();
fieldTextBlock.Text = latestField.Name;
fieldTextBlock.FontSize = 15;
fieldTextBlock.Height = 33;
// Add Drag and Drop Handler for TextBlock
var dragTranslation2 = new TranslateTransform();
fieldTextBlock.RenderTransform = dragTranslation2;
dragTranslationDict2.Add(fieldTextBlock.Name, dragTranslation2);
// Add TextBlock to a list to control later
TxtBlockList.Add(fieldTextBlock);
TextBoxStack.Children.Add(fieldTextBox);
TextBlockStack.Children.Add(fieldTextBlock);
}
I'll skip the usual "What have you tried?" question and say you probably can get what you need by setting the Margin property on the TextBox - the Margin property will add "space" around the control size as a sort of padding (not to be confused with the Padding property, which will add space inside the control extents)
I don't know what you are really up to, but either use the Margin-property of the textbox. It defines, how much space there will be around the control,
See MSDN for more information.

TreeListControl within each NavbarControl Group

I'm very new to WPF and I'm attempting to create a treelist navigation within each navbar group. Because the number of navbar groups and treelists are dynamic I have to make them in code rather than them be pre-defined in XAML.
I have tested the following so far which is meant to define the navbar group's content rather than use the default item
private void CreateGroup2(NavBarControl navBar)
{
NavBarGroup group2 = new NavBarGroup();
group2.Header = "Custom Content";
//Specify that the group's content should be defined via the Content property
group2.DisplaySource = DisplaySource.Content;
TreeListControl tree = new TreeListControl();
tree.ItemsSource = TreeList_DataBinding.Stuff.GetStuff();
group2.Content = tree;
navBar.Groups.Add(group2);
}
This gives an Exception: Grid.InfiniteGridSizeException: By default, an infinite grid height is not allowed since all grid rows will be rendered and hence the grid will work very slowly. To fix this issue, you should place the grid into a container that will give a finite height to the grid, or you should manually specify the grid's Height or MaxHeight. Note that you can also avoid this exception by setting the TreeListControl.AllowInfiniteGridSize static property to True, but in that case the grid will run slowly.
I'm a little confused as I'm not using a grid? Can anyone give any pointers what's wrong and how I can add a treview under each navbar group?
Thank You
It feels a bit wrong answering my own question but I managed to get it working using the following
private void CreateGroup2(NavBarGroup navBarGroup)
{
System.Windows.Controls.TreeView treeview = new System.Windows.Controls.TreeView();
TreeViewItem nod = new TreeViewItem();
nod.Header = "Tree Node1";
treeview.Items.Add(nod);
TreeViewItem nod1 = new TreeViewItem();
nod1.Header = "Tree Node2";
treeview.Items.Add(nod1);
TreeViewItem nod2 = new TreeViewItem();
nod2.Header = "Tree Node3";
nod1.Items.Add(nod2);
//StackPanel stcPnl = new StackPanel(); /optiona
//stcPnl.Children.Add(treeview);
//navBarGroup.Content = stcPnl;
navBarGroup.Content = treeview;
navBarGroup.DisplaySource = DisplaySource.Content;
}

Dynamic and Immutable UIElement Arrays

I have a WrapPanel that contains multiple Canvas of the same size. Each Canvas has some UIElements (i.e. TextBox, TextBlock, Buttons etc) as children. The creation of each Canvas (including its UIElement children) and the number of Canvas to be created are all done in run-time code behind (no XAML).
Initially I did the following, which works:
// declare as class properties, so all function can access them
WrapPanel wp = new WrapPanel();
Canvas[] cv = new Canvas[500];
TextBox[] tb = new TextBox[500];
// A function (e.g. a Button_Click event) that generates multiple Canvas in a WrapPanel
for (int i = 0; i<myInt; i++)
{
cv[i] = new Canvas();
tb[i] = new TextBox();
cv[i].Children.Add(tb[i]);
wp.Children.Add(cv[i]);
}
The above code is straight forwards works OK - Until I implement add, minus and destroy buttons where I could
1. Add an additional `Canvas` on a click event
2. Remove the last `Canvas` on a click event
3. Destroy a specific `Canvas` in the `WrapPanel` on a click event (may ba a little cross icon in each `Canvas`)
If I process some combination of the above 3 actions, I could easily create UIElements of the same index or create Canvas that goes out of the range of what it had been declared initially.
I looked into List however, each Canvas have different properties (each also has UIElement Children with different properties) and I can't figure out how List would solve it. A way for me to go around that is to declare a super large Array size for Canvas (e.g. Canvas[] cv = new Canvas[99999] but I though that's not very efficient.
Also, if I use List, how could I change properties of a specific UIElement after the they are generated? E.g. If i add 10 Canvas and add to List, and after they are all generated, I need to select the 5th Canvas and change a TextBox.Text, how do I access it like I did in an Array (i.e. tb[5].Text = "Hello")?
Can anyone show me some approaches to this problem?
Just a direct translation on how to do this with a list instead below. Given your code I don't know why you want to keep track of the canvas and textbox'es in a list - you can just access the children collection of the WrapPanel directly instead - let's assume you do need these separate collections for now.
WrapPanel wp = new WrapPanel();
List<Canvas> cvList = new List<Canvas>();
List<TextBox> tbList = new List<TextBox>();
public void Init()
{
int myInt = 500;
// in a function (e.g. a Button_Click event) to generate the multiple Canvas in a WrapPanel
for (int i = 0; i < myInt; i++)
{
Canvas cv = new Canvas();
TextBox tb = new TextBox();
cv.Children.Add(tb);
wp.Children.Add(cv);
cvList.Add(cv);
tbList.Add(tb);
}
}
public void AddCanvas()
{
Canvas cv = new Canvas();
TextBox tb = new TextBox();
cv.Children.Add(tb);
wp.Children.Add(cv);
cvList.Add(cv);
tbList.Add(tb);
}
public void RemoveCanvas()
{
wp.Children.RemoveAt(wp.Children.Count-1);
cvList.RemoveAt(cvList.Count - 1);
tbList.RemoveAt(cvList.Count - 1);
}
Edit for added comment:
E.g. If i add 10 Canvas, and after
they are all generated, I need to
select the 5th Canvas and change a
TextBox.Text, how do I access it like
I did in an Array (i.e. tb[5].Text =
"Hello")?
You can just access the children directly. You know you only added Canvas elements to your WrapPanel. So you could do (wp is the WrapPanel again):
TextBox textbox = (wp.Children[5] as Canvas).Children[0] as TextBox;
textbox.Text = "Hello";
Just operate directly on the WrapPanel's Children collection.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
AddCanvasToWrapPanel(this.TestWrapPanel);
RemoveLastCanvasFromWrapPanel(this.TestWrapPanel);
AddCanvasToWrapPanel(this.TestWrapPanel);
DestroyCanvasAtWrapPanelIndex(this.TestWrapPanel, 0);
}
private void AddCanvasToWrapPanel(WrapPanel wp)
{
TextBox t = new TextBox();
Canvas c = new Canvas();
c.Children.Add(t);
wp.Children.Add(c);
}
private void RemoveLastCanvasFromWrapPanel(WrapPanel wp)
{
wp.Children.RemoveAt(wp.Children.Count - 1);
}
private void DestroyCanvasAtWrapPanelIndex(WrapPanel wp, int index)
{
wp.Children.RemoveAt(index);
}
}
}

Categories

Resources