Home > database >  How to pass the ViewModel instance into a user defined Command
How to pass the ViewModel instance into a user defined Command

Time:10-17

Tips: Chinese content is just a translation of English content, you don't need to care about them, and please don't delete them 提示: 英文内容只是中文内容的翻译, 你不需要关心它们, 也请不要删掉它们

Knowing that I now have an MVVM MAUI project. There is a BindingList<string> Names property in the ViewModel, which generates controls in the view like this:
已知我现在有一个 MVVM 的 MAUI 项目. 在 ViewModel 中有一个 BindingList<string> Names 属性, 它会在视图中这样进行生成控件:

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

I want after each item, there is a Button that can be used to delete the current item, and the Button logic is called via Command.
That is to say, in the logic of this Command, operate the Names property in ViewModel and delete one of them, so this Command needs to be passed into ViewModel
我希望在每一项后, 都有一个 Button 可以用来删除当前项, 并且 Button 逻辑通过 Command 调用.
也就是说, 这个 Command 的逻辑中, 操作 ViewModel 中的 Names 属性, 删除其中一项, 所以这个 Command 需要传入 ViewModel

Normally, if you declare the Command directly in the ViewModel, and then instantiate it, create a new Command and pass in the current ViewModel object, so that the Command can manipulate the Names in the ViewModel
正常来讲, 如果直接在 ViewModel 中声明这个 Command, 然后实例化的时候, 新建 Command 并传入当前 ViewModel 对象, 这样 Command 就可以操作这个 ViewModel 中的 Names

However, for CollectionView, his DataTemplate binding cannot be bound to the properties of the BindingContext set by Page, and his BindingContext is each item in Names. In this way, the instance of Command cannot be obtained.
但是, 对于 CollectionView, 他的 DataTemplate 绑定是无法绑定到 Page 设定的 BindingContext 的属性的, 他的 BindingContext 是 Names 中的每一项. 这样就拿不到 Command 的实例

enter image description here

enter image description here

If you define it in Resource, you can get the Command instance through StaticResource, but how does ViewModel pass in this Command?
如果通过在 Resource 中定义的话, 倒是可以通过 StaticResource 来拿到 Command 实例, 但是, ViewModel 改如何传入这个 Command 呢?

I want to achieve this using MVVM design pattern
我想要使用 MVVM 设计模式实现这一目的

CodePudding user response:

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

You want this.

Edit: To clarify. You are tapping on a DataTemplate bound to specific model. With this you are telling to go search a parent of this what you are tapping (your ViewModel) and use its command. (Since your Model doesn't have any commands).

CodePudding user response:

I hope I got your problem right.

The way out of the textbook: Don't use "Binding Names" but bind to ViewModels again. The default should always be to bind to ViewModels.

But sometimes for me this was too much work and what you can do is to use the DataContext of a parent element. The nicest way for me it to give the root element a name and bind to this like:

{Binding DataContext.YourProperty, ElementName=YourRootElement} With CommandParameter={Binding} you get your element. [edit] You can also use FindAnchestor, but personally I don't likethat as it easily breaks when you change your XAML structure. [edit2] It seems MAUI does not support binding by ElementName, at least I couldn't find it. So you will have to use the anchestor binding type https://learn.microsoft.com/en-us/dotnet/maui/fundamentals/data-binding/relative-bindings#bind-to-an-ancestor

PS: Use BindingList only if your really need it, otherwise use ObservableCollection

  • Related