简体   繁体   中英

C# WPF MVVM - How can I access a specific item from ItemsControl/DataTemplate?

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();
    }

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM