英文:
Binding ContextActions MenuItem with CommunityToolkit.Mvvm in MAUI
问题
I have a problem in binding a ReplyCommand
to a MenuItem
in the ContextAction
.
<ListView x:Name="listDictionaries" ItemsSource="{Binding Dictionaries}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<VerticalStackLayout>
<Label Text="{Binding Name}"
FontSize="18"
FontAttributes="Bold" />
</VerticalStackLayout>
<ViewCell.ContextActions>
<MenuItem Text="Set as default"
Command="{Binding Source={x:Reference listDictionaries}, Path=BindingContext.SetDefaultCommand}"
CommandParameter="{Binding .}" />
</ViewCell.ContextActions>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I associated a ViewModel to this view and in the page's code, I wrote:
DictionaryListViewModel vm;
public DictionaryList(DictionaryListViewModel model)
{
vm = model;
BindingContext = vm;
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await vm.Init();
}
The Init()
method reads from the database a list of Dictionary
items (Dictionary
is my class, not the .NET class). In the associated ViewModel, I created this command:
[RelayCommand]
public async Task SetDefault(Dictionary dictionary)
{
Message = "Set as default: " + SelectedDictionary.Name;
}
When I run the application, I can see a black screen, but the items are there. I can click on an item and display the value of the cell in a DisplayAlert
, but the binding is not working.
If I remove the ViewCell.ContextActions
, the list displays the item as expected.
What is the correct way to bind the ReplyCommand
to the MenuItem
?
Update
I followed the example in the Microsoft documentation, but I still have issues.
The only way I found to have this MenuItem
working is to use Clicked
and then in the code-behind invoke a function.
<MenuItem Text="Set as default"
Clicked="OnSetAsDefault"
CommandParameter="{Binding .}" />
And then in the code-behind:
public async void OnSetAsDefault(object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
Dictionary dictionary = (Dictionary)mi.CommandParameter;
}
It is working, but at this point, I don't understand the meaning of the Command
or RelayCommand
.
英文:
I have a problem in binding a ReplyCommand
to a MenuItem
in the ContextAction
.
<ListView x:Name="listDictionaries" ItemsSource="{Binding Dictionaries}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<VerticalStackLayout>
<Label Text="{Binding Name}"
FontSize="18"
FontAttributes="Bold" />
</VerticalStackLayout>
<ViewCell.ContextActions>
<MenuItem Text="Set as default"
Command="{Binding Source={x:Reference listDictionaries}, Path=BindingContext.SetDefaultCommand}"
CommandParameter="{Binding .}" />
</ViewCell.ContextActions>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I associated to this view a ViewModel and in the code of the page I wrote:
DictionaryListViewModel vm;
public DictionaryList(DictionaryListViewModel model)
{
vm = model;
BindingContext = vm;
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
await vm.Init();
}
The Init()
reads from the database a list of Dictionary
items (Dictionary
is my class not the NET class). In the associated ViewModel I created this command:
[RelayCommand]
public async Task SetDefault(Dictionary dictionary)
{
Message = "Set as default: " + SelectedDictionary.Name;
}
When I run the application, I can see a black screen but the items are there. As you can see, I can click on one item an display the value of the cell in an DisplayAlert
but the binding is not working.
If I remove the ViewCell.ContextActions
, the list displays the item as expected.
What is correct way to bind the ReplyCommand
to the MenuItem
?
Update
I followed the example in the Microsoft documentation but I still have issues.
The only way I found to have this MenuItem
working is to use Clicked
and then in the code behind invoke a function.
<MenuItem Text="Set as default"
Clicked="OnSetAsDefault"
CommandParameter="{Binding .}" />
and then in the code
public async void OnSetAsDefault(object sender, EventArgs e)
{
var mi = ((MenuItem)sender);
Dictionary dictionary = (Dictionary)mi.CommandParameter;
}
It is working but at this point I don't understand the meaning of the Command
or RelayCommand
.
答案1
得分: 1
我可以在Windows平台上复现你的问题。但在Android平台上它工作正常。
当你在一个需要参数的方法上使用[RelayCommand]
属性时,似乎会出现一个新问题。如果你删除参数,它就会工作。比如:
[RelayCommand]
public async Task SetDefault()
{
Message = "设为默认:";
}
你也可以像官方示例一样,使用ICommand
而不是RelayCommand
,它使用了**INotifyPropertyChanged
接口而不是ObservableObject
类**。你可以查看官方示例关于使用MVVM绑定上下文菜单项的部分。
我已经测试了使用INotifyPropertyChanged
接口的ICommand
而不是ObservableObject
的RelayCommand
,它可以正常工作。
另外,你也可以尝试在GitHub上为CommunityToolkit.Mvvm in MAUI提交一个新的问题。
英文:
I can reproduce your problem in my project on the windows platform. But it worked well in the android platfrom.
It seems a new issue when you use the [RelayCommand]
attribute on a method which needs a parameter. If you delete the parameter, it will work. Such as:
[RelayCommand]
public async Task SetDefault()
{
Message = "Set as default: " ;
}
And you can also use the ICommand instead of the RelayCommand just as the official sample which used the INotifyPropertyChanged interface instead of the ObservableObject class did. You can check the official sample about Binding ContextActions MenuItem with MVVM.
I have tested using ICommand of the INotifyPropertyChanged interface instead of the RealyCommand of the ObservableObject. It worked.
In addition, you can also try to post a new issue for CommunityToolkit.Mvvm in MAUI on the github.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论