英文:
.Net Maui Switch using MVVM Community ToolKit return Object Sender to View Model
问题
我在Xaml页面中有多个Switches,我正在努力理解在使用Switches时处理MVVM概念以及处理状态更改等。我试图在视图模型中捕获xaml.cs文件中可用的对象和参数。
来自Microsoft关于Switches的标准Switch Xaml。
<Switch Toggled="OnToggled" />
同一页面的Xaml.cs文件
void OnToggled(object sender, ToggledEventArgs e)
{
// 我有了发送者,所以现在可以定位开关并更改值、颜色等。
}
现在对我来说,这是一个巨大的cough,我试图跳入Mvvm,但我未能领会。
我已经按照关于Mvvm的每个指南/演示/教程,但我无法弄清楚如何使用Maui社区工具包做几乎相同的事情,并使用View Model可以剔除代码中的Xaml.cs元素。因为我认为页面不应该知道视图,反之亦然。
我的当前代码如下:-
SettingsPage.xaml
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyProject.Views.SettingsPage"
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:vm="clr-namespace:MyProject.ViewModels"
x:DataType="vm:SettingsPageViewModel"
BackgroundColor="{DynamicResource PageBackGround}">
<ContentPage.Content>
<StackLayout>
<Switch IsToggled = "True"
<Switch.Behaviors>
<mct:EventToCommandBehavior
x:TypeArguments="x:Object"
EventName="Toggled"
Command="{Binding ToggledCommand}" />
</Switch.Behaviors>
</Switch>
</StackLayout>
</ContentPage.Content>
</ContentPage>
SettingsPage.xaml.cs
namespace MyProject.Views;
public partial class SettingsPage : ContentPage
{
ILogger<SettingsPage> _logger;
public SettingsPage(SettingsPageViewModel settingsPageViewModel, ILogger<SettingsPage> logger)
{
InitializeComponent();
BindingContext = settingsPageViewModel;
_logger = logger;
_logger.LogInformation("Navigation to Settings Page.");
}
}
SettingsPageViewModel.cs
namespace MyProject.ViewModels
{
public partial class SettingsPageViewModel : BaseViewModel
{
ILogger<SettingsPageViewModel> _logger;
LogController LogController;
public SettingsPageViewModel(ILogger<SettingsPageViewModel> logger)
{
_logger = logger;
LogController = a LogController();
}
// 在这里,我想捕获对象,以便我可以在页面上有多个开关,并能够识别它们以更改值等,了解它们的状态。
[RelayCommand]
public void Toggled(ToggledEventArgs e)
{
var bangingMyheadAgainstAWall = "e";
}
}
}
我也尝试过不使用EventToCommandBehaviour,只使用标准的Toggled,IsToggled,OnToggled,IWishIknewWhichSwitchWasToggled,但我无法将属性传递到视图模型,或者我已经陷入困境,有点困惑。
对于帮助/推动我正确处理这种情况的任何帮助/方向,我将不胜感激。提前感谢。
英文:
I have multiple Switches in a Xaml page and I am struggling to grasp the concept of MVVM when using Switches and handling State Changes etc. I am trying within a view model to capture the object and argument within the ViewModel which is available within the xaml.cs file.
A standard Switch Xaml from Microsoft on Switches.
<Switch Toggled="OnToggled" />
The same page Xaml.cs File
void OnToggled(object sender, ToggledEventArgs e)
{
// I have the sender so can target the switch now and change values colours etc.
}
Now it is this massive cough for me leap into Mvvm which I am failing to grasp.
I have followed every single guide/demo/tutorial on Mvvm but I can not figure out how doing the near same thing using Maui Community Toolkit and using a View Model I can cut out the Xaml.cs element of my code. As I believe the page should not be aware of the View vice versa.
My current code is as follows :-
SettingsPage.xaml
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyProject.Views.SettingsPage"
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
xmlns:vm="clr-namespace:MyProject.ViewModels"
x:DataType="vm:SettingsPageViewModel"
BackgroundColor="{DynamicResource PageBackGround}">
<ContentPage.Content>
<StackLayout>
<Switch IsToggled = "True"
<Switch.Behaviors>
<mct:EventToCommandBehavior
x:TypeArguments="x:Object"
EventName="Toggled"
Command="{Binding ToggledCommand}" />
</Switch.Behaviors>
</Switch>
</StackLayout>
</ContentPage.Content>
</ContentPage>
SettingsPage.xaml.cs
namespace MyProject.Views;
public partial class SettingsPage : ContentPage
{
ILogger<SettingsPage> _logger;
public SettingsPage(SettingsPageViewModel settingsPageViewModel, ILogger<SettingsPage> logger)
{
InitializeComponent();
BindingContext = settingsPageViewModel;
_logger = logger;
_logger.LogInformation("Navigation to Settings Page.");
}
}
SettingsPageViewModel.cs
namespace MyProject.ViewModels
{
public partial class SettingsPageViewModel : BaseViewModel
{
ILogger<SettingsPageViewModel> _logger;
LogController LogController;
public SettingsPageViewModel(ILogger<SettingsPageViewModel> logger)
{
_logger = logger;
LogController = new LogController();
}
// Here I want to capture the object so that I can have multiple switches on the page and be able to identify them to change values etc for what states they are in.
[RelayCommand]
public void Toggled(ToggledEventArgs e)
{
var bangingMyheadAgainstAWall = "e";
}
}
}
I have also tried without using the EventToCommandBehaviour and just used standard Toggled, Istoggled, OnToggled, IWishIknewWhichSwitchWasToggled but I just can not get the properties through to the view model or I have backed myself in to a corner and am a little confused.
Any help/ push in the correct direction to help me handle this situation correctly would be greatly appreciated. Thanks in Advance.
答案1
得分: 1
似乎你有点把事情搞复杂了。你可以大部分忽略事件和通过这种方式获取/设置值。关键在于数据绑定。
IsToggled
,就像.NET MAUI中的大多数属性一样,是一个可绑定属性。这意味着你可以将视图模型中的属性绑定到它,控件会在发生更改时更新该属性,不需要事件。
你的代码大部分已经到位了!你可以移除事件到命令的部分,你不需要它。还可以移除
将你的Switch
改为:<Switch IsToggled = "{Binding MyProperty}"/>
在你的SettingsPageViewModel
中添加一个像这样的属性,假设使用了MVVM Toolkit:
[ObservableProperty]
private bool myProperty;
现在每当切换开关时,代码中的属性应该反映出新的值,反之亦然。
据我理解,你的思路是这样的:我需要一个事件来捕获开关的切换,但这不是MVVM,所以我需要一个Command
来做同样的事情。
通常情况下不是这样的。Command
真的只是用于执行逻辑,而不是设置或检索控件值。
如果我可以提供最后一条不请自来的建议:如果你刚开始学习MVVM,尝试在不使用Toolkit的情况下使用它。我喜欢MVVM Toolkit,它很棒,但它也有很多魔法。如果你熟悉MVVM,它会提高效率,而且非常有帮助。但如果刚开始,它只会增加困惑。
英文:
It seems like you're overcomplicating things. You can forget mostly about events and getting/setting values that way. The key here is data binding.
IsToggled
, like most properties in .NET MAUI, is a bindable property. This means that you can bind a property from your view model to it, and the control will update that property whenever something changes, no event needed.
You're mostly there with your code though! You can remove the event to command stuff, you don't need it. Also remove
Change your Switch
to: <Switch IsToggled = "{Binding MyProperty}"/>
And on your SettingsPageViewModel
add a property like this, this is assuming the use of the MVVM Toolkit:
[ObservableProperty]
private bool myProperty;
Now whenever the switch is toggled, the property in code should reflect the new value and vice versa.
From what I understand that you're doing is your thought process was: I need an event to catch the switch being toggled, but that's not MVVM, so I need a Command
to do the same thing.
Usually that's not the case. A Command
really only is for executing logic, not setting or retrieving control values.
If I can offer a last piece of unsolicited advice: if you're just starting out with MVVM, try doing so without the Toolkit. I love the MVVM Toolkit, it's amazing, but it also has a lot of magic. If you know your way around MVVM it's a productivity boost and can be really helpful. If you're just starting, it will only add to the confusion.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论