如何从ListView.ItemTemplate内部访问父ViewModel?

时间:2019-06-23 00:28:56

标签: xaml uwp

我有一个简单的ListView,它是由ObservableCollection填充的。绑定列表后,我想从此vm内部访问父ItemTemplate视图模型,以便可以绑定名为cmd_delete_mesh的命令。对于UWP Xaml应用程序(不是wpf)如何完成?

<ListView x:Name="mesh_list" SelectedItem="{x:Bind vm.selected_mesh, Mode=TwoWay}" ItemsSource="{x:Bind vm.meshes}">
 <ListView.ItemTemplate>
  <DataTemplate>
   <ListViewItem>
     <Button Command="{Binding cmd_delete_mesh}"/>

3 个答案:

答案 0 :(得分:0)

您可以这样做:

<ListView x:Name="mesh_list" SelectedItem="{x:Bind vm.selected_mesh, Mode=TwoWay}"    ItemsSource="{x:Bind vm.meshes}">
 <ListView.ItemTemplate>
  <DataTemplate>
   <ListViewItem>
     <Button Command="{Binding ElementName=mesh_list, Path=DataContext.vm.cmd_delete_mesh}"/>

答案 1 :(得分:0)

很遗憾,我是通过代码执行此操作的...我将很快发布一个示例代码

答案 2 :(得分:0)

您可以在模型中定义命令并在其中声明一个事件。在ViewModel中,初始化“ meshes”集合时,可以为该集合中的每个项目注册此事件。然后,在执行命令时,您只需要引发事件并在事件处理程序中进行一些操作即可。

我制作了一个简单的代码示例供您参考:

<ListView x:Name="mesh_list" SelectedItem="{x:Bind ViewModel.selected_mesh, Mode=TwoWay}" ItemsSource="{x:Bind ViewModel.meshes,Mode=OneWay}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:SubTest">
                <ListViewItem>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{x:Bind Name }"></TextBlock>
                        <Button Command="{x:Bind cmd_delete_mesh}" Content="delete"/>
                    </StackPanel>
                </ListViewItem>
            </DataTemplate>
        </ListView.ItemTemplate>
</ListView>
public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
        ViewModel = new Test("test data");
    }
    private Test ViewModel { get; set; }
}
public class Test : ViewModelBase
{
    public string Name { get; set; }

    private SubTest _selected_mesh;

    public SubTest selected_mesh
    {
        get { return _selected_mesh; }
        set
        {
            if (_selected_mesh != value)
            {
                _selected_mesh = value;
                RaisePropertyChanged("selected_mesh");
            }
        }
    }

    public ObservableCollection<SubTest> meshes { get; set; } = new ObservableCollection<SubTest>();

    public Test(string name)
    {
        this.Name = name;
        for (int i = 0; i < 10; i++)
        {
            var sub = new SubTest() { Name = "String " + i };
            sub.DeleteParentItem += Test_DeleteParentItem;
            meshes.Add(sub);
        }
    }

    private void Test_DeleteParentItem()
    {
        if (selected_mesh != null)
        {
            DeleteItem(selected_mesh);
        }
    }

    private void DeleteItem(SubTest subTest)
    {
        //TODO...
    }
}
public class SubTest
{
    public RelayCommand cmd_delete_mesh { get; set; }

    public string Name { get; set; }

    public event Action DeleteParentItem;

    public SubTest()
    {
        cmd_delete_mesh = new RelayCommand(DeleteItem);
    }

    private void DeleteItem()
    {
        if (DeleteParentItem != null)
        {
            DeleteParentItem.Invoke();
        }
    }
}

注意ViewModelBaseRelayCommand来自mvvmlight

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;