C
C#2y ago
Dawnbomb

❔ How do i assign or change Z order of a button? (Dock buttons)

I'm trying to make a list of buttons appear, and dock them top down to a grid in C#. As with most things WPF, this seems annoyingly difficult. I googled for like 20 minutes and got no answers. I'm not even sure if i'm searching for the wright terms. How do i dock a generated button, and then have the next one also be docked, below the first one? I assume i probably use MyButton.VerticalAlignment = VerticalAlignment.Top; but i don't know what the term is to refer to docking or Z index. Because its not Dock or ZIndex or Index or like 10 other things i tried.
27 Replies
canton7
canton72y ago
Are you sure you want z-index? Don't you just want the buttons to appear staked underneath each other? A Grid is probably the wrong panel for the job. You can use it, and programatically add a new row each time you add a button to it, but meh A StackPanel / DockPanel would be better: they automatically stack things next to each other. For the StackPanel set Orientation="Vertical", for the DockPanel set LastChildFill="False" and set DockPanel.Dock="Top" on each child But, this is WPF and we can do better. An ItemsControl will bind to a collection objects, and render each object as a button. Something like:
<ItemsControl x:name="ButtonList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl x:name="ButtonList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Then
this.ButtonList.ItemsSource = new List<string>() { "Button 1", "Button 2", "Button 3" };
this.ButtonList.ItemsSource = new List<string>() { "Button 1", "Button 2", "Button 3" };
Of course you'll need to get a bit more complex, as each button will presumably do something when it's clicked, so you'll need to wire that up And if you're using MVVM rather than the code-behind, you can do <ItemsControl ItemsSource="{Binding ...}">... of course
Dawnbomb
Dawnbomb2y ago
I'll probably try it a bit later or tomorrow, but thanks. Also yes i just wanted them stacked. @canton7 wait but how do i set DockPanel.Dock="Top", thats still not a property of a button, and im back to my initial question >_>; also, isn't Z the order things appear in? maybe not. But then what is?
canton7
canton72y ago
It's an attached property. It's defined by DockPanel and it can be applied to any control
canton7
canton72y ago
<Button DockPanel.Dock="Top"... /> in xaml, DockPanel.SetDock(button, Dock.Top) in code. See the docs: https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.dockpanel.dock?view=windowsdesktop-7.0
DockPanel.Dock Attached Property (System.Windows.Controls)
Gets or sets a value that indicates the position of a child element within a parent DockPanel.
canton7
canton72y ago
Z order is when you have multiple controls on top of each other: it's which appears on top X and Y being the horizontal and vertical axes, and Z being the axis which points out of the screen
Dawnbomb
Dawnbomb2y ago
@canton7 okay well, i have this dockpanel setup, and i can't figure out how to move a button up one
canton7
canton72y ago
The order of elements in the dockpanel's Children determines the other they're displayed in
Dawnbomb
Dawnbomb2y ago
the closest i got was DockPanel.SetDock(SelectedDoc, Dock.Top + 1); that moves it...right, but still not up. well yes, and my question still stands, how do i move a button up one.
canton7
canton72y ago
Uh... Dock is an enum. If you add to to Top, you probably do get Dock.Right
Dawnbomb
Dawnbomb2y ago
oh i see, well
canton7
canton72y ago
You swap it with the child before it in DockPanel's Children collection?
Dawnbomb
Dawnbomb2y ago
uh, how? i still don't know the name of whatever is used to track the order you said its not Z, and presumably not X or Y, but that doesn't tell me what it is, only what it isn't.
canton7
canton72y ago
Let's see. DockPanel's Children property is a UIElementCollection (https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.panel.children?view=windowsdesktop-7.0), and if we look at the docs for that (https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.uielementcollection?view=windowsdesktop-7.0), we can see that it has a RemoveAt method (https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.uielementcollection.removeat?view=windowsdesktop-7.0) and an Insert method which takes an index to insert at (https://learn.microsoft.com/en-us/dotnet/api/system.windows.controls.uielementcollection.insert?view=windowsdesktop-7.0) It's the same as having a List<int> with the elements { 1, 2, 3 }, and you want to move the 3 so that it's before the 2 So you list.RemoveAt(2) then list.Insert(1, 3)
Dawnbomb
Dawnbomb2y ago
so i have to remove and insert, i can't just...move it?
canton7
canton72y ago
You're welcome to look at the docs for UIElementCollection that I linked and see for yourself
Dawnbomb
Dawnbomb2y ago
i guess thats a no this is so bad, ugh
canton7
canton72y ago
There's no "name of whatever" that's used to track order. Things are added to the DockPanel in the order that they're in its Children property. The first child gets placed, then the second child gets placed into the remaining space, and so on I mean, if the vertical order was somehow controlled by some int property, then swapping the order of two elements still requires 3 operations. So I'm not sure what it's any worse...
Dawnbomb
Dawnbomb2y ago
do children really not have an order? Yuck.
canton7
canton72y ago
And it's trivial to make your own Swap method if you like Yes, the children's order is given by the order that they appear in the Children collection.... How else would you do it?
child1.Order = 3;
children.Add(child1);
child2.Order = 4;
children.Add(child2);
// etc
child1.Order = 3;
children.Add(child1);
child2.Order = 4;
children.Add(child2);
// etc
? Then what if two children have the same value for their Order property? Swapping two children becomes:
int tmp = child1.Order;
child1.Order = child2.Order;
child2.Order = tmp;
int tmp = child1.Order;
child1.Order = child2.Order;
child2.Order = tmp;
Is that really better? The DockPanel then has to do children.SortBy(x => x.Order) before it can place its children. All of that is entirely more complex than just placing its children in the order that they've been added.
Dawnbomb
Dawnbomb2y ago
how else? by using like, order +1 man, i feel like i haven't found a single thing WPF does better then winforms. Ugh
canton7
canton72y ago
Also it means that you'll end up with XAML like:
<DockPanel>
<Child DockPanel.Dock="Top" DockPanel.Order="3"/>
<Child DockPanel.Dock="Left" DockPanel.Order="1"/>
<Child DockPanel.Dock="Top" DockPanel.Order="2"/>
</DockPanel>
<DockPanel>
<Child DockPanel.Dock="Top" DockPanel.Order="3"/>
<Child DockPanel.Dock="Left" DockPanel.Order="1"/>
<Child DockPanel.Dock="Top" DockPanel.Order="2"/>
</DockPanel>
Is that really easier to understand than just listening the children in order? Use winforms then 🙂
Dawnbomb
Dawnbomb2y ago
i really want to, but i was harassed by plenty of people to use WPF despite how much harder it is for some supposed payoff i have yet to see even a little. anyway so...
canton7
canton72y ago
I mean, you're never going to find it better with that attitude So just use what you're used to
Dawnbomb
Dawnbomb2y ago
how does remove and insert even work. I feel like insert requires a new thing, and remove only deletes, unless maybe i misunderstand the word remove, and it doesn't actually kill the target
canton7
canton72y ago
Remove just removes the target from the collection. It doesn't "kill" it It's really quite a frustrating experience trying to help someone with such a shitty attitude, so I'm afraid I'm out. Good luck!
Dawnbomb
Dawnbomb2y ago
likewise, getting patronized and told how i should just find it better and my attitude is the problem is really fucking annoying. like ah yes, it's only my imagination that everything is harder here, despite actually tons of online talk about the exact same complaints i'm to stupid, its my fault for not magically knowing the answer, how dare i. Ah yes, if i just smile more, WPF will magically change it's command list to not be so confusing. Its not hard to understand, its an attitude problem. >_>;
Accord
Accord2y ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.