I have multiple DataTemplates with a TextBox inside and they are selected with a DataTemplateSelector. The TextBoxes represent nodes within a tree. When I click on a TextBox at runtime, the command ZoomPlusButtonCommand should be fired. That works. But I want to know, which TextBox in my ObservableCollection has fired this command. Every node has a id, so I want this id as command parameter. How can I do that?
XAML:
<DataTemplate x:Key="RootNode" DataType="{x:Type vm:TreeNodeViewModel}">
<TextBox Tag="{Binding NodeTag}" Text="{Binding Node.Description}" Margin="{Binding NodeMargin}">
<TextBox.Style>
<Style>
<Setter Property="TextBox.Background" Value="#FFF6212D"/>
...
<Style.Triggers>
<Trigger Property="TextBox.IsMouseOver" Value="True">
<Setter Property="TextBox.BorderBrush" Value="AliceBlue"/>
</Trigger>
...
</Style.Triggers>
</Style>
</TextBox.Style>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=DataContext.ZoomPlusButtonCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</DataTemplate>
MainViewModel:
public class MainViewModel : ViewModelBase
{
// list of all existing nodes in the tree editor
public ObservableCollection<TreeNodeViewModel> Nodes { get; set; }
// commands
private ZoomPlusButtonCommand _zoomPlusButtonCommand;
public ZoomPlusButtonCommand ZoomPlusButtonCommand
{
get
{
return _zoomPlusButtonCommand;
}
set
{
_zoomPlusButtonCommand = value;
}
}
public MainViewModel()
{
Nodes = new ObservableCollection<TreeNodeViewModel>();
Nodes.Add(new TreeNodeViewModel(4,0,"TEST1",new Thickness(0, 100, 0, 0)));
Nodes.Add(new TreeNodeViewModel(56, 1, "TEST2", new Thickness(100, 150, 0, 0)));
Nodes.Add(new TreeNodeViewModel(56, 2, "TEST3", new Thickness(200, 200, 0, 0)));
// initialize commands
_zoomPlusButtonCommand = new ZoomPlusButtonCommand(this);
}
}
ViewModel of the TextBox (Node):
public class TreeNodeViewModel : ViewModelBase
{
private TreeNode _node;
public TreeNode Node
{
get
{
return _node;
}
set
{
_node = value;
RaisePropertyChanged(nameof(Node));
}
}
private string _nodeTag;
public string NodeTag
{
get
{
return _nodeTag;
}
set
{
_nodeTag = value;
RaisePropertyChanged(nameof(NodeTag));
}
}
private Thickness _nodeMargin;
public Thickness NodeMargin
{
get
{
return _nodeMargin;
}
set
{
_nodeMargin = value;
RaisePropertyChanged(nameof(NodeMargin));
}
}
public TreeNodeViewModel(int id, int level, string tag, Thickness margin)
{
Node = new TreeNode();
Node.Id = id;
Node.Level = level;
Node.Description = "Knoten";
NodeTag = tag;
NodeMargin = margin;
}
}
Command:
public class ZoomPlusButtonCommand : ICommand
{
private MainViewModel mainViewModel;
public ZoomPlusButtonCommand(MainViewModel vm)
{
mainViewModel = vm;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
if (mainViewModel.ComboBoxZoomSelectedIndex - 1 >= 0)
{
mainViewModel.ComboBoxZoomSelectedIndex -= 1;
}
}
public event EventHandler CanExecuteChanged
{
// only implemented to suppress the compiler warning that this event will never be used
add { }
remove { }
}
}
assuming your ICommand
implementation (the ZoomPlusButtonCommand
class) can handle command parameters, you can alter the code like this:
XAML
<DataTemplate x:Key="RootNode" DataType="{x:Type vm:TreeNodeViewModel}">
<TextBox Tag="{Binding NodeTag}" Text="{Binding Node.Description}" Margin="{Binding NodeMargin}">
<TextBox.Style>
<Style>
<Setter Property="TextBox.Background" Value="#FFF6212D"/>
...
<Style.Triggers>
<Trigger Property="TextBox.IsMouseOver" Value="True">
<Setter Property="TextBox.BorderBrush" Value="AliceBlue"/>
</Trigger>
...
</Style.Triggers>
</Style>
</TextBox.Style>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource AncestorType=Window, Mode=FindAncestor}, Path=DataContext.ZoomPlusButtonCommand}" CommandParameter="{Binding NodeTag}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</DataTemplate>
MainViewModel
public class MainViewModel : ViewModelBase
{
// list of all existing nodes in the tree editor
public ObservableCollection<TreeNodeViewModel> Nodes { get; set; }
// commands
private ZoomPlusButtonCommand<string> _zoomPlusButtonCommand;
public ZoomPlusButtonCommand<string> ZoomPlusButtonCommand
{
get
{
return _zoomPlusButtonCommand;
}
set
{
_zoomPlusButtonCommand = value;
}
}
public MainViewModel()
{
Nodes = new ObservableCollection<TreeNodeViewModel>();
Nodes.Add(new TreeNodeViewModel(4,0,"TEST1",new Thickness(0, 100, 0, 0)));
Nodes.Add(new TreeNodeViewModel(56, 1, "TEST2", new Thickness(100, 150, 0, 0)));
Nodes.Add(new TreeNodeViewModel(56, 2, "TEST3", new Thickness(200, 200, 0, 0)));
// initialize commands
_zoomPlusButtonCommand = new ZoomPlusButtonCommand<string>(this);
}
}