Reputation: 1271
I've created an XAML dialog window. For the most part, I need to populate this window dynamically, which is something I've never tried to tackle before, and I can't find anything on either this site or MSDN. Here's what I can show from the .xaml
:
<GroupBox Header="Pipe Segments" Height="Auto" Margin="5,0,0,0">
<StackPanel Orientation="Vertical">
<StackPanel x:Name="PipeSegRow1" Orientation="Horizontal" Margin="0,5,0,0">
<StackPanel x:Name="PipeSegR1C1" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR1C2" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR1C3" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR1C4" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR1C5" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR1C6" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
</StackPanel>
<StackPanel x:Name="PipeSegRow2" Orientation="Horizontal" Margin="0,5,0,0">
<StackPanel x:Name="PipeSegR2C1" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR2C2" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR2C3" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR2C4" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR2C5" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR2C6" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
</StackPanel>
<StackPanel x:Name="PipeSegRow3" Orientation="Horizontal" Margin="0,5,0,0">
<StackPanel x:Name="PipeSegR3C1" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR3C2" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR3C3" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR3C4" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR3C5" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR3C6" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
</StackPanel>
<StackPanel x:Name="PipeSegRow4" Orientation="Horizontal" Margin="0,5,0,0">
<StackPanel x:Name="PipeSegR4C1" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR4C2" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR4C3" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR4C4" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR4C5" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR4C6" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
</StackPanel>
<StackPanel x:Name="PipeSegRow5" Orientation="Horizontal" Margin="0,5,0,0">
<StackPanel x:Name="PipeSegR5C1" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR5C2" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR5C3" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR5C4" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR5C5" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
<StackPanel x:Name="PipeSegR5C6" Orientation="Vertical" Margin="5,0,0,0" Width="90"></StackPanel>
</StackPanel>
</StackPanel>
</GroupBox>
There's a couple more of those in the window. What I am trying to accomplish is this: Place new Checkbox
's in the StackPanel
rows and columns dynamically from the contents of a List<T>
. Here's what I'm trying, but I'm not sure if it will work, or if I'm even coming at this the right way. I'd like to point out in advance the the List<T>
being using initially below is not the one for the GroupBox
above. Sorry for the confusion - just know that they're essentially the same thing.
public void PopulateWindow()
{
int itr = 1; //TO SCROLL THROUGH THE ROWS AND COLUMNS
var fecPipes = new FilteredElementCollectoR(m_pDoc); //GET ALL PIPES
var lstRVTPipes = fecPipes.OfCategory(BuiltInCategory.OST_PipeCurves).
OfClass(typeof(PipeType)); //FILTER RVT PIPES
var lstMEPSizes = fecPipes.OfCategory(BuiltInCategory.OST_PipeCurves).
OfClass(typeof(MEPSize)); //FILTER NOMINAL DIAMETERS
var lstPipeSeg = fecPipes.OfCategory(BuiltInCategory.OST_PipeCurves).
OfClass(typeof(PipeSegment)); //FILTER PIPE SEGMENTS
foreach (PipeType pPipe in lstRVTPipes)
{
CheckBox cb = new CheckBox(); //CREATE NEW CHECK BOX
cb.Height = 15; //SET CHECK BOX HEIGHT
cb.Name = pPipe.FamilyName.ToString(); //SET THE NAME OF THE CHECK BOX
cb.Content = pPipe.FamilyName.ToString(); //SET THE CONTENT DISPLAY OF THE CHECK BOX
switch (itr) //PLACE THE CHECK BOX
{
case 1:
cb.BindingGroup = RVTPipeR1C1.BindingGroup; //DOES THIS WORK?
RVTPipeR1C1.DataContext = cb; //DOES THIS WORK?
/* I'D LIKE TO DO SOMETHING LIKE:
* RVTPipeR1C1.Add(cb); OR
* cb.Location = RVTPipeR1C1.Location;
* BUT THAT'S NOT A OPTION... :-( */
break;
// THEN IT KEEPS GOING LIKE THIS FOR A WHILE...
//
//
}
itr++;
}
}
If anyone can tell me how to place these items, or if I'm doing anything right/wrong, I'd greatly appreciate it! Any links to anything that helps is great too! Thanks!
Upvotes: 1
Views: 1424
Reputation: 823
For dynamically placing collection of elements you can use ItemsControl
. For it you can read here: https://msdn.microsoft.com/ru-ru/library/system.windows.controls.itemscontrol(v=vs.110).aspx, https://professorweb.ru/my/WPF/binding_and_styles_WPF/level20/20_2.php and easy example of using it is here: http://www.wpf-tutorial.com/list-controls/itemscontrol/.
In code you create ObservableCollection<T>
for your elements, where T
is ViewModel
for your CheckBox
'es.
For your ItemsControl
you must set StackPanel
as ItemsControl.ItemsPanel
, ItemsSource="{Binding Path=Elements}"
(where Elements
is your ObservableCollection<T>
) and in ItemsControl.ItemTemplate
add DataTemplate
for your CheckBox
'es.
I hope, my tips will help you)
Upvotes: 2
Reputation: 169280
You can add a UIElement to a StackPanel by adding it to the StackPanel's Children property:
PipeSegR1C1.Children.Add(cb);
A StackPanel has no concept of rows and columns though. It simply arranges child elements into a single line that is oriented horizontally or vertically depending on the value of the Orientation property: https://msdn.microsoft.com/en-us/library/system.windows.controls.stackpanel(v=vs.110).aspx
If you want to organize your controls in a flexible grid area that consists of columns and rows you could use a Grid element and add ColumnDefinition and RowDefinitions to it. Please refer to MSDN for more information: https://msdn.microsoft.com/en-us/library/system.windows.controls.grid(v=vs.110).aspx#Properties
Upvotes: 0