【问题标题】:C# WPF MVVM - How can I access a specific item from ItemsControl/DataTemplate?C# WPF MVVM - 如何从 ItemsControl/DataTemplate 访问特定项目?
【发布时间】:2017-06-23 14:03:45
【问题描述】:

我有一个窗口和一个 ItemsControl,我在其中使用按钮添加任务。 如果我有一些任务,我想访问我按下新按钮的特定项目(或行)。 我不知道如何访问这个 ItemControl 中的每个项目。有没有优雅的方法?

目前我只能访问最后一项,因为它保存在绑定中..

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

【问题讨论】:

  • 您不能在 ItemsControl 中选择项目,因为它基本上只是元素的显示。我建议使用派生自 ItemsControl 并支持使用 SelectedItems 属性跟踪当前项目的 ListView。
  • @Lennart 由于按钮本身在 ItemsControl 内,我认为他想要按钮的相应项目,而不是 SelectedItem

标签: c# wpf xaml mvvm


【解决方案1】:

如果要将按钮对应的列表项绑定到命令方法的参数,可以使用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>

【讨论】:

  • 您的命令链接到一个方法。您应该能够使用带参数的方法,因为 RelayCommand 支持参数(请参阅this answer
  • 非常感谢,我不知道为什么我之前没有尝试过。只需要编辑我的 RelayCommand 类。现在可以正常使用了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 1970-01-01
相关资源
最近更新 更多