I have a TreeView with the following definition:
<TreeView ItemsSource="{Binding Folders, UpdateSourceTrigger=PropertyChanged}" x:Name="tree">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Folders, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{Binding Name}" >
<Label.InputBindings>
<KeyBinding Key="Delete"
Command="{Binding DataContext.DeleteFolderCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding DataContext.SelectFolderCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
CommandParameter="{Binding ElementName=tree, Path=SelectedItem}" />
</Label.InputBindings>
</Label>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
This view is boud to it's Code-Behind-File with:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
The InputBinding for the LeftDoubleClick just works fine.
But the InputBinding for the 'Delete'-Key doesn't work.
The Command where the KeyBinding is bound to looks like:
public ICommand DeleteFolderCommand
{
get { return _deleteFolderCommand; }
set
{
_deleteFolderCommand = value;
OnPropertyChanged();
}
}
and in the constructor I define:
DeleteFolderCommand = new RelayCommand(DeleteFolder);
and the DeleteFolder-Method just looks like:
private void DeleteFolder(object parameter)
{
// Break-Point here will not be reached
}
What am I doing wrong?
I've already checked the Output-Window for Binding-Errors, but there are none.
I managed it by handling the KeyBinding directly at the TreeView
<TreeView ItemsSource="{Binding Folders, UpdateSourceTrigger=PropertyChanged}" x:Name="tree">
<TreeView.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DataContext.DeleteFolderCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"/>
</TreeView.InputBindings>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Folders, UpdateSourceTrigger=PropertyChanged}">
<Label Content="{Binding Name}">
<Label.InputBindings>
<MouseBinding MouseAction="LeftDoubleClick"
Command="{Binding DataContext.SelectFolderCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
CommandParameter="{Binding ElementName=tree, Path=SelectedItem}" />
</Label.InputBindings>
</Label>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Related
I have a treeview and i want have a menu on right click. On clicking menu item a command should get called with the item. I have tried different solution but keep getting error as below.
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression
My treeview is as below
<TreeView ItemsSource="{Binding Buildings}" Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}" Grid.RowSpan="4">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Gates}" DataType="{x:Type local:Floor}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Floors}" DataType="{x:Type local:Building}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" >
<TextBlock.ContextMenu>
<ContextMenu>
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.EditCmd}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:Gate}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
Also in viewmodel
private ICommand editCmd;
public ICommand EditCmd
{
get
{
if (editCmd == null)
editCmd = new DelegateCommand(EditObjectFunction);
return editCmd;
}
}
I have tried different solution like This but could not solve the problem
The UserControl is not a visual ancestor of the MenuItem since a ContextMenu resides in its own element tree.
But you could bind the Tag property of the TextBlock to the UserControl and then bind the Command property of the MenuItem to the PlacementTarget property of the ContextMenu:
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" Tag="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
<TextBlock.ContextMenu>
<ContextMenu>
<ContextMenu.ItemContainerStyle>
<Style TargetType="MenuItem">
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}, Path=PlacementTarget.Tag.DataContext.EditCmd}"/>
</Style>
</ContextMenu.ItemContainerStyle>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</StackPanel>
I'm having a problem binding to my command in my ListBox ItemTemplate. My command is defined in my ViewModel, but because I'm using ItemsSource for my listbox, that's set as the DataContext.
<ListBox ItemsSource="{Binding CreatureModel.TypeFlagsValues}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}" Command="{Binding SetCommand">
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I've tried using RelativeSource
Command="{Binding SetCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type vm:CreatureEditorViewModel}}}"
And
<DataTemplate DataType="vm:CreatureEditorViewModel">
<CheckBox Content="{Binding}" Command="{Binding SetCommand}" CommandParameter="test">
</CheckBox>
</DataTemplate>
I feel like I'm missing something simple here.
You almost did it right with RelativeSource.
Try this:
Command="{Binding Path=DataContext.SetCommand,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ItemsControl}} }"
Alternatively you may give a name to your listbox (e.g. "_listBox" and use the following binding:
Command="{Binding DataContext.SetCommand, ElementName=_listBox}
Try setting the ElementName and Path on the Command; you have to set the x:Name on the ListBox, then you can reference the parent DataContext.
<ListBox x:Name="list" ItemsSource="{Binding CreatureModel.TypeFlagsValues}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}" Command="{Binding ElementName=list,
Path=DataContext.SetCommand}">
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm building a treeview with HierarchicalDataTemplates and would like to bind the nodes to a command from my MainViewModel. I guess there is some conflict with the scopes, since the binding works if I e.g. use a button and define it outside of the treeview. If I define it inside, however, it does not work.
I've searched through Stackoverflow and found several solutions but none that worked for me. Jehof e.g. suggested here to use
<Button Command="{Binding DataContext.Command,
RelativeSource={RelativeSource AncestorLevel=2, AncestorType=TreeViewItem}}"
CommandParameter="{Binding}" />
but that did not work. Thank you for any suggestions!
<TreeView ItemsSource="{Binding _questions}" Grid.Row="0" Margin="10" BorderThickness="1">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Question}" ItemsSource="{Binding Converter={StaticResource QuestionConverter}}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:MainOption}" ItemsSource="{Binding MainOptions}">
<StackPanel Orientation="Horizontal">
<CheckBox Content="{Binding Path=Name}" />
/////////////////////////////////////
<Button Command="{Binding ThisIsMyCommand}" Content="Click Me"/>
/////////////////////////////////////
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
Is your TreeView-Control inside a Window or UserControl?
If you are inside a Window:
<Button Command="{Binding DataContext.Command, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" CommandParameter="{Binding}" />
and for UserControl
<Button Command="{Binding DataContext.Command, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" CommandParameter="{Binding}" />
I have the following DataTemplate used in a TreeView.
How do I have LeftMouseClick on the ContentPresenter to bind to a property of the DataType in MVVM fashion?
Thanks for any help (or better idea).
<DataTemplate x:Key="sharedTemplate">
<StackPanel Orientation="Horizontal">
<CheckBox
Focusable="False"
IsChecked="{Binding IsChecked}"
VerticalAlignment="Center"
/>
<ContentPresenter
Content="{Binding Name, Mode=OneTime}"
Margin="2,0"
/>
</StackPanel>
</DataTemplate>
<TreeView
ItemContainerStyle="{StaticResource TreeViewItemStyle}"
ItemsSource="{Binding ReportTree}" >
<TreeView.Resources>
<HierarchicalDataTemplate
DataType="{x:Type r:ReportViewModel}"
ItemsSource="{Binding Children}"
>
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource sharedTemplate}" />
</HierarchicalDataTemplate>
................
Addendum: This works!
<DataTemplate DataType="{x:Type r:PrinterViewModel}">
<!--Bind the ContentControl to the DataType-->
<ContentControl Content="{Binding}"
ContentTemplate="{StaticResource sharedTemplate}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<h:EventToCommand
Command="{Binding DataContext.SelectItem, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ContentControl>
</DataTemplate>
Addendum: As it turns out, the above Interaction.Trigger does work to correctly send the selected viewmodel back to the DataContext of the TreeView. Problem solved.
I have an wpf application.I want to show the selected item in the Combo box.
I get an error saying Cant use both DisplayMemberPath and Item Template.
My ItemsSource is not of string type
its a class called "StockExchange"
Following is my code :
<telerik:RadComboBox Grid.Column="1" DisplayMemberPath="StockExchangeName" Name="cmbStockExchange" Foreground="White" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Margin="118,14,0,0" VerticalAlignment="Top" Width="100" Height="23" ItemsSource="{Binding StockExchange, Mode=TwoWay}" SelectedItem="{Binding SelectedStockExchange,Mode= TwoWay}" telerik:StyleManager.Theme="Summer" TabIndex="3">
<telerik:RadComboBox.ItemTemplate >
<DataTemplate>
<CheckBox Name="StockExchange" Content="{Binding StockExchangeName}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<Commands:EventToCommand Command="{Binding DataContext.StockExchangeCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=StockExchange}" ></Commands:EventToCommand>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<Commands:EventToCommand Command="{Binding DataContext.StockExchangeUnCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=StockExchange}" ></Commands:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>
what is solution for this? how can I display single or multiple selected Items in a Combo box?
<telerik:RadComboBox Grid.Column="1" Name="cmbStockExchange" Foreground="White" HorizontalAlignment="Left" HorizontalContentAlignment="Center" Margin="118,14,0,0" VerticalAlignment="Top" Width="100" Height="23" ItemsSource="{Binding StockExchange, Mode=TwoWay}" SelectedItem="{Binding SelectedStockExchange,Mode= TwoWay}" telerik:StyleManager.Theme="Summer" TabIndex="3">
<telerik:RadComboBox.ItemTemplate >
<DataTemplate>
<CheckBox Name="StockExchange" Content="{Binding StockExchangeName}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<Commands:EventToCommand Command="{Binding DataContext.StockExchangeCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=StockExchange}" ></Commands:EventToCommand>
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<Commands:EventToCommand Command="{Binding DataContext.StockExchangeUnCheckedCmd,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type telerik:RadWindow}}}" CommandParameter="{Binding ElementName=StockExchange}" ></Commands:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
Create a Textblock that Shows the selected item StockExchangeName
<TextBlock Text="{Binding Path=SelectedItem.StockExchangeName, ElementName=cmbStockExchange}" />
If you select CheckBox, no item is shown selected in comboBox because no item is selected since click event is handled by checkbox.
You can bind IsChecked with IsSelected value of ComboBoxItem so that on click of checkbox corresponding item gets selected.
<CheckBox Content="{Binding StockExchangeName}"
IsChecked="{Binding IsSelected, RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=ComboBoxItem}}"/>
This will show checkBox in comboBox because you have provided template with checkBox in it for comboBoxItem.