XAML 如何将ViewModel示例传递到用户定义的Command中

yc0p9oo0  于 2022-12-07  发布在  其他
关注(0)|答案(3)|浏览(190)

Tips: Chinese content is just a translation of English content, you don't need to care about them, and please don't delete them 提示: 英文内容只是中文内容的翻译, 你不需要关心它们, 也请不要删掉它们
知道我现在有一个MVVM MAUI项目,ViewModel中有一个BindingList<string> Names属性,它在视图中生成如下控件:
已知我现在有一个 MVVM 的 MAUI 项目. 在 ViewModel 中有一个 BindingList<string> Names 属性, 它会在视图中这样进行生成控件:

<CollectionView ItemsSource="{Binding Names}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <StackLayout Orientation="Horizontal">
                <Label Text="{Binding}"/>
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

我希望在每个项目之后,都有一个按钮,可以用来删除当前项目,并且通过命令调用按钮逻辑。
也就是说,在这个Command的逻辑中,操作ViewModel中的Names属性,删除其中的一个,所以这个Command需要传入ViewModel
我希望在每一项后, 都有一个 Button 可以用来删除当前项, 并且 Button 逻辑通过 Command 调用.
也就是说, 这个 Command 的逻辑中, 操作 ViewModel 中的 Names 属性, 删除其中一项, 所以这个 Command 需要传入 ViewModel
通常,如果您直接在ViewModel中声明Command,然后示例化它,则创建一个新的Command并传入当前ViewModel对象,以便Command可以操作ViewModel中的Names
正常来讲, 如果直接在 ViewModel 中声明这个 Command, 然后示例化的时候, 新建 Command 并传入当前 ViewModel 对象, 这样 Command 就可以操作这个 ViewModel 中的 Names
但是对于CollectionView,他的DataTemplate绑定不能绑定到Page设置的BindingContext的属性上,他的BindingContext是Names中的每一项,这样就不能得到Command的示例。
但是, 对于 CollectionView, 他的 DataTemplate 绑定是无法绑定到 Page 设定的 BindingContext 的属性的, 他的 BindingContext 是 Names 中的每一项. 这样就拿不到 Command 的示例

如果在Resource中定义它,则可以通过StaticResource获取Command示例,但是ViewModel如何传入该Command?
如果通过在 Resource 中定义的话, 倒是可以通过 StaticResource 来拿到 Command 示例, 但是, ViewModel 改如何传入这个 Command 呢?
我想使用MVVM设计模式来实现这一点
我想要使用 MVVM 设计模式实现这一目的

zi8p0yeb

zi8p0yeb1#

Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:MyViewModel}}, Path=DetailsCommand}"

你想要这个。
编辑:澄清一下。你点击了一个绑定到特定模型的DataTemplate。通过这个,你可以告诉你去搜索你点击的这个模型的父模型(你的ViewModel),并使用它的命令。(因为你的Model没有任何命令)。

xfyts7mz

xfyts7mz2#

首先,我注意到您希望使用MVVM,因此可以使用ObservableCollection而不是BindingList。
其次,可以使用relative-bindings作为解决方案。

<Button Text="Delete"
        Command="{Binding Source={RelativeSource AncestorType={x:Type local:MainPageViewModel}}, Path=DeleteItemCommand}"
        CommandParameter="{Binding}"/>

第三,您还可以为页面设置一个名称,并将该名称绑定到按钮源。

<Button Text="Delete" Command="{Binding BindingContext.DeleteCommand, Source={x:Reference MainPage}}" CommandParameter="{Binding .}" />
8tntrjer

8tntrjer3#

我希望我没弄错你的问题。
教科书的出路:不要使用“绑定名称”,而是再次绑定到ViewModels。默认值应始终是绑定到ViewModels。
但是有时候对我来说这太麻烦了,你能做的就是使用父元素的DataContext。对我来说最好的方法是给予根元素一个名字,然后绑定到如下的元素:
{Binding DataContext.YourProperty, ElementName=YourRootElement}使用CommandParameter={Binding}你可以得到你的元素。[edit]你也可以使用FindAnchor,但是我个人不喜欢这样,因为当你改变XAML结构时,它很容易被破坏。[edit 2]看来MAUI不支持通过ElementName绑定,至少我找不到它。所以你必须使用Anchor绑定类型https:learn.microsoft.com/en-us/dotnet/maui/fundamentals/data-binding/relative-bindings#bind-to-an-ancestor
PS:只有在你真正需要的时候才使用BindingList,否则使用ObservableCollection

相关问题