I have a ``TreeViewwhich uses a customItemsPanelto show the first level of items in aStackPanel, but I need to show subitems in aStackPaneltoo. The problem is, the second level of items are shown in aWrapPanel, and asHierarchicalDataTemplatedoesn't have anItemsPanel` property I'm not sure how to do this. This is my xaml:
<TreeView x:Name="treGlobalCards">
<TreeView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel IsItemsHost="True" Orientation="{Binding Orientation,RelativeSource={x:Static RelativeSource.TemplatedParent}}"
MaxWidth="{Binding ActualWidth,RelativeSource={RelativeSource AncestorType={x:Type ScrollContentPresenter}}}"/>
</ItemsPanelTemplate>
</TreeView.ItemsPanel>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate x:Key="CardTypeTemplate" ItemsSource="{Binding Cards}">
<TextBlock Text="{Binding Path=CardType}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Create a new DataTemplate that uses a StackPanel and set the HierachicalDataTemplate's "ItemTemplate" to that new DataTemplate.
i.e.
<DataTemplate x:Key="someTemp">
<StackPanel />
</DataTemplate>
<HierarchicalDataTemplate x:Key="hierTemp" ItemSource="{Binding}" ItemTemplate="{StaticResource someTemp}" />
Related
We have following xaml code to display context menu and fire command when delete menu is clicked.
For the context menu item, I would like to bind command which is present in DataContext of ItemsControl. We tried with RelativeSource={RelativeSource TemplatedParent} but as the tree is created dynamically (using dataContext) it is not able to find DeleteCommand.
<Grid x:Name="MyGrid" >
<ItemsControl ItemsSource="{Binding Path=TreeRoot.Children}">
<ItemsControl.ItemTemplate>
<HierarchicalDataTemplate>
<StackPanel>
<Label Background="Black" Content="{Binding Path=DisplayText}"/>
<TreeView ItemsSource="{Binding Converter={StaticResource myCompositeNodeConverter}}" >
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:CompositeNode}" ItemsSource="{Binding Path=Children}" >
<TextBlock Text="{Binding Path=DisplayText}" Foreground="Black"></TextBlock>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:LeafNode}" ItemsSource="{Binding Path=Children}">
<TextBlock Text="{Binding Path=DisplayText}"></TextBlock>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ContextMenu>
<ContextMenu >
<MenuItem Header="Delete" Command="{Binding DeleteCommand}" />
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
</StackPanel>
</HierarchicalDataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
How do we bind DeleteCommand for context menu item to DataContext of ItemsControl?
I want to reuse the the ItemsControl from my ListView and its not really hard to put the ItemsControle into an Template.
The problem is, I want to change the DataTemplate when I use my ItemsControlTemplate.
<ListView DataContext="{Binding Input}">
<ItemsControl ItemsSource="{Binding Columns}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Label Content="{Binding ColumnHeader}"></Label>
</StackPanel>
<ListView Grid.Row="1">
<ItemsControl ItemsSource="{Binding ColumnData}">
<ItemsControl.ItemTemplate>
<!--This should be changed when I reuse my ItemsControl-->
<DataTemplate>
<Button Content="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ListView>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ListView>
You can use a Resource to set that ItemTemplate dynamically. Just provide a default Resource of DataTemplate, when you need to change it, override that resource (using the same key and place in a closer place to the control).
<ListView Grid.Row="1">
<ItemsControl ItemsSource="{Binding ColumnData}"
ItemTemplate="{StaticResource templateKey}"/>
</ListView>
Then define a resource with x:Key of templateKey like this:
<Window.Resources>
<DataTemplate x:Key="templateKey">
<Button Content="{Binding}"/>
</DataTemplate>
<Window.Resources>
Here is an example of overriding the template, in which we place another DataTemplate inside the ListView's Resources:
<ListView DataContext="{Binding Input}">
<ListView.Resources>
<DataTemplate x:Key="templateKey">
<CheckBox Content="{Binding}"/>
</DataTemplate>
</ListView.Resources>
<!-- ... -->
</ListView>
If you want to update the template at runtime, you need to use DynamicResource instead of StaticResource.
I have a listbox (with normal vertical orientation), each element of which is a listbox with horizontal orientation.
I want to have a ScrollBar inside of internal listbox. So, my problem is how to set width of internal listbox according to real current width of external.
My current code is:
<Window.Resources>
<HierarchicalDataTemplate x:Key="ItemTemplateSchedule">
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>My-Very-Long-Item-Nimber-1___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Nimber-2___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Nimber-3___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Nimber-4___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Nimber-5___</ListBoxItem>
</ListBox>
</HierarchicalDataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemTemplate="{StaticResource ItemTemplateSchedule}" >
>
</ListBox>
</Grid>
Current screenshot:
.
UPD1
Ok, answer to my question is setting of width for internal listbox, thanks to #sa_ddam213:
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=ActualWidth}"
Now I want add some new control in each row of external listbox:
<HierarchicalDataTemplate x:Key="ItemTemplateSchedule">
<StackPanel Orientation="Horizontal" Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=ActualWidth}">
<TextBlock Text="This is Text in a TextBlock"/>
<ListBox >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>My-Very-Long-Item-Number-1___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Number-2___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Number-3___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Number-4___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Number-5___</ListBoxItem>
</ListBox>
</StackPanel>
</HierarchicalDataTemplate>
And it doesn't work now! Is it possible to solve this problem? Current screenshot:
You can use a FindAncestor to bind to the parent ListBox ActualWidth
Example:
<Window.Resources>
<HierarchicalDataTemplate x:Key="ItemTemplateSchedule">
<ListBox Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListBox}, Path=ActualWidth}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBoxItem>My-Very-Long-Item-Nimber-1___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Nimber-2___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Nimber-3___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Nimber-4___</ListBoxItem>
<ListBoxItem>My-Very-Long-Item-Nimber-5___</ListBoxItem>
</ListBox>
</HierarchicalDataTemplate>
</Window.Resources>
Result:
Accordion item Visibility property can be bound like this:
<layoutToolkit:Accordion x:Name="MyAccordion">
<layoutToolkit:AccordionItem Visibility="{Binding IsVisible, Converter={StaticResource VisibilityConverter}}">
...
</layoutToolkit:AccordionItem>
</layoutToolkit:Accordion>
But how to bind it when using Accordion.ItemTemplate?
<layoutToolkit:Accordion ItemsSource="{Binding AcordionItems}" x:Name="MyAccordion">
<layoutToolkit:Accordion.ItemTemplate>
<DataTemplate>
...
</DataTemplate>
</layoutToolkit:Accordion.ItemTemplate>
<layoutToolkit:Accordion.ContentTemplate>
<DataTemplate>
...
</DataTemplate>
</layoutToolkit:Accordion.ContentTemplate>
</layoutToolkit:Accordion>
I can bind IsVisible to elements inside DataTemplate, but then an empty accordion item is displayed. I need to be able to show/hide the whole accordion item.
I ended up using StackPanel with multiple Accordions:
<StackPanel Orientation="Vertical">
<ItemsControl ItemsSource="{Binding AcordionItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<layoutToolkit:Accordion Visibility="{Binding IsVisible, Converter=
{StaticResource VisibilityConverter}}">
<layoutToolkit:AccordionItem>
...
</layoutToolkit:AccordionItem>
</layoutToolkit:Accordion>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
I want to create a ListBox filled with checkboxes in WPF, and I want to databind the "Content" value with a simple string value. However when I try <CheckBox Margin="5" Content="{Binding}" /> the app crashes.
This is what I have. ( I'm sure I am missing something simple )
<ListBox Grid.Row="1" IsSynchronizedWithCurrentItem="True" x:Name="drpReasons">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" >
</WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
<DataTemplate DataType="{x:Type System:String}">
<CheckBox Margin="5" Content="{Binding}" />
</DataTemplate>
</ListBox.Resources>
</ListBox>
You created an infinitely recursive DataTemplate. By setting the DataTemplate for String, and then setting the Content of CheckBox to a String, the CheckBox will use the DataTemplate itself, so you'll have CheckBoxes within CheckBoxes and so on.
You can fix it by putting a TextBlock inside the CheckBox explicitly:
<ListBox x:Name="drpReasons" Grid.Row="1" IsSynchronizedWithCurrentItem="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal">
</WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Resources>
<DataTemplate DataType="{x:Type sys:String}">
<CheckBox Margin="5">
<TextBlock Text="{Binding}"/>
</CheckBox>
</DataTemplate>
</ListBox.Resources>
</ListBox>