How to find datacontext of parent's parent for dynamic control - wpf

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?

Related

How to set ItemTemplate and Template for contexmenu along with data binding for ItemTemplate

On click of toggle button I want to show a context menu. As I want to change the visual appearance of context menu, I have created controltemplate and data template as below,
<TabItem>
<TabItem.HeaderTemplate>
<DataTemplate>
<ContextMenu ItemSource="{Binding Collection}">
<ContextMenu.Template>
<ControlTemplate>
<Grid Margin="10">
<ListBox Width="150" Height="70"/>
</Grid>
</ControlTemplate>
<ContextMenu.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox Content="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu.Template>
</ContextMenu>
</DataTemplate>
</TabItem.HeaderTemplate>
</TabItem>
Post this change I could see only a LisBox being shown clicking upon toggle button. I am not able to visualize the Data template that I had set (Checkbox). Data binding is also not working. Not able to figure out what could be the issue.
You should bind the ItemsSource property of the ListBox to the ItemsSource of the ContextMenu and define an ItemTemplate for the ListBox:
<ContextMenu ItemsSource="{Binding Collection}">
<ContextMenu.Template>
<ControlTemplate TargetType="ContextMenu">
<Grid Margin="10">
<ListBox ItemsSource="{TemplateBinding ItemsSource}" Width="150" Height="70">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>

WPF DataTemplate and binding with TextBlock

<Window.Resources>
<DataTemplate x:Key="pointGroupTemplate" DataType="{x:Type ac:PointGroup}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
<DataTemplate x:Key="tt2" DataType="{x:Type ac:PointGroup}">
<TextBlock Text="{Binding PointsCount}"/>
</DataTemplate>
</Window.Resources>
the first template works well with:
<ComboBox x:Name="comboBox1" ItemTemplate="{StaticResource pointGroupTemplate}" SelectionChanged="ComboBox1_SelectionChanged"
Height="25" Margin="0,5,0,5">
but i want to use the second one in a textblock
<TextBlock x:Name="textBlock1" Text="{Binding ElementName=comboBox1 ,Path=SelectedItem ?????}"/>
anyhelp.
In order to have a DataTemplate applied, you need a ContentPresenter or ContentControl:
<ContentControl ContentTemplate="{StaticResource tt2}"
Content="{Binding SelectedItem, ElementName=comboBox1}"/>

Binding to ViewModel instance from View

I have program which initializes PersonsViewModel in MainWindowViewModel's constructor.
public MainWindowViewModel()
{
PersonsViewModel viewModel = new PersonsViewModel();
}
In MainWindow.xaml, PersonsViewModel and PersonsView are connected.
<Window.Resources>
<DataTemplate DataType="{x:Type vm:PersonsViewModel}">
<vw:PersonsView />
</DataTemplate>
</Window.Resources>
I use viewModel as ItemsControl ItemsSource.
<ItemsControl ItemsSource="{Binding viewModel}" Margin="4" />
Now my program opens UserControl and I need to set instance of PersonsViewModel to UserControl.DataContext.
<UserControl.DataContext>
<vm:PersonsViewModel />
</UserControl.DataContext>
Am I creating a new instance of PersonsViewModel. If I am doing so, then how I can bind it to PersonsViewModel instance? Because I have following code in UserControl. I have PersonsList bound to ItemsSource and I need to bind Command to PersonsViewModel instance.
<ItemsControl ItemsSource="{Binding PersonsList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Width="50" Text="{Binding Name}" />
<Button Content="Ok" Width="20" Margin="3" Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}, Path=DataContext.Command}" CommandParameter="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You can remove the UserControl.DataContext and Add ItemsControl.ItemTemplate. Since each ItemsControl is bound to List of person viewmodel. Each item will get the viewmodel as its datacontext. Refer the below code.
<ItemsControl ItemsSource="{Binding ViewModels}" Margin="4">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type vm:PersonsViewModel}">
<vw:PersonsView />
</DataTemplate>
</ItemsControl.ItemTemplate>

How to edit an item in the treeview in wpf

My TreeView ItemTemplate looks like below.
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Connections}">
<WrapPanel >
<CheckBox VerticalAlignment="Center" Command="{Binding UpdateConnections}" CommandParameter="{Binding}" IsChecked="{Binding Status, Mode=TwoWay}" Focusable="False" Style="{StaticResource ResourceKey=TreeView_CheckBox_Style}"></CheckBox>
<TextBlock Text="{Binding Name}" Style="{StaticResource ResourceKey=treeTextBoxStyle}" />
</WrapPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
I am using MVVM. I would like to edit the TextBox if my tree item starts with "s".
I basically double click my TreeViewItem and I should be able to type in it.
How do i do it ?

WPF: HierarchicalDataTemplate ItemsPanel

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}" />

Resources