Reputation: 45
I have a window and a ItemsControl in which I add tasks with a button. If I got a few tasks, I want to access the specific item (or line) where I pressed the new button. I don't know how to access each item in this ItemControl. Is there a elegant way?
Currently I can only access to the last item, because it's saved in the binding..
XAML:
<StackPanel Grid.Row="1" Grid.ColumnSpan="4" HorizontalAlignment="Left">
<ItemsControl ItemsSource="{Binding TaskList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1"
Grid.ColumnSpan="3"
VerticalAlignment="Center"
FontSize="25"
Text="{Binding Name}" />
<Button
Height="30"
Width="30"
Margin="5"
Grid.Column="3"
Style="{DynamicResource RoundCorner}"
Command="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.GetNameCommand}" />
</Grid>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
XAML.CS:
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowView();
}
MainWindowView():
/// <summary>
/// Collection of tasks.
/// </summary>
public ObservableCollection<Task> TaskList { get; set; }
/// <summary>
/// Task class for the task list.
/// </summary>
public class Task
{
public string Name { get; set; }
public Task(string name)
{
Name = name;
}
public string GetTaskName()
{
string name = Name;
return name;
}
}
[...]
/// <summary>
/// Default constructor.
/// </summary>
public MainWindowView()
{
// Init properties.
MainWindowTitle = "Hello World";
MainWindowHeight = "130";
MainWindowWidth = "455";
TaskList = new ObservableCollection<Task>();
// Commands.
this.ResizeWindowCommand = new RelayCommand(ResizeWindowPlus);
this.TaskPlusCommand = new RelayCommand(TaskPlus);
this.GetNameCommand = new RelayCommand(GetName);
ResizeWindow();
}
[...]
/// <summary>
/// Adds a task to the list.
/// </summary>
public void TaskPlus()
{
// Get TaskName of TextInput.
TextInput txtÍnput = new TextInput();
txtÍnput.ShowDialog();
// Add the task to the list.
if (string.IsNullOrEmpty(txtÍnput.TaskName))
return;
TaskList.Add(new Task(txtÍnput.TaskName));
ResizeWindowPlus();
}
Upvotes: 1
Views: 1144
Reputation: 3188
If you want to bind the button's corresponding list item to the command method's parameter, you can use CommandParameter="{Bnding}"
:
<StackPanel Grid.Row="1" Grid.ColumnSpan="4" HorizontalAlignment="Left">
<ItemsControl ItemsSource="{Binding TaskList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1"
Grid.ColumnSpan="3"
VerticalAlignment="Center"
FontSize="25"
Text="{Binding Name}" />
<!-- Here we add the CommandParameter -->
<Button
Height="30"
Width="30"
Margin="5"
Grid.Column="3"
Style="{DynamicResource RoundCorner}"
Command="{Binding RelativeSource={RelativeSource AncestorType=ItemsControl}, Path=DataContext.GetNameCommand}"
CommandParameter="{Binding}" />
</Grid>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
Upvotes: 1