Model-View-ViewModel(MVVM)是一种架构设计模式,用于实现用户界面,通过其表示逻辑(其ViewModel)将UI(View)与其数据(Model)分开。
我想使用MVVM在WPF中制作工厂SIM卡,但传送带不起作用。按下按钮后正在创建蓝色盒子,但它们不会移动,我也认为它们的大小是错误的 使用
在数据层中,我通过从Firestore获取数据来实现用户介绍。我的目标是最大程度地减少烟台查询数量以提高性能并避免不必要的成本。
我正在窗口和Mac平台中编码一个应用程序。我已经完成了这样的代码: <Button x:Name="ForwardButton" Text=">" Command="{Binding ForwardCommand}"> 它运行良好。但是按钮是CLCIK事件。用户将多次单击按钮。因此,我想更改键盘事件的方式。键盘中的右键将是使用该功能的更好方法。 现在,我不知道如何让Maui与CommunityToolkit一起捕捉键盘活动。 有人向我展示这样的代码: <ContentPage xmlns:mvvm="clr-namespace:CommunityToolkit.Mvvm.ComponentModel;assembly=CommunityToolkit.Mvvm" ...> ... <ContentPage.Behaviors> <mvvm:EventToCommandBehavior EventName="KeyUp" SourceObject="{x:Reference Name=myTextBox}" Command="{Binding EnterKeyPressedCommand}"/> </ContentPage.Behaviors> </ContentPage> 但不幸的是,它行不通。 那么谁能告诉我该怎么办?很长一段时间以来,我一直被这个问题所阻止。 谢谢 没有API可以在.NET MAUI中检测到关键事件。因此,您可以使用平台本机API来做到这一点。 对于Windows 在contenpage.cs中输入以下代码: protected override void OnHandlerChanged() { base.OnHandlerChanged(); #if WINDOWS var winview = this.Handler.PlatformView as Microsoft.Maui.Platform.ContentPanel; winview.PreviewKeyUp += (s, e) => { if(e.Key == Windows.System.VirtualKey.Enter) { (((BindingContext as TargetViewModel).EnterCommand) as RelayCommand).Execute(null); //excute the command } }; #endif } 为MacCatalyst 在\ platforms \ macCatalyst \appdelegate.cs中输入以下代码 public override void PressesBegan(NSSet<UIPress> presses, UIPressesEvent evt) { if(App.Current.MainPage == TargetPage) { foreach (UIPress p in presses) { var key = p.Key; if (key.Characters == "\r") { ((((App.Current.MainPage as TargetPage).BindingContext as TargetViewModel).EnterCommand) as RelayCommand).Execute(null); } } } base.PressesBegan(presses, evt); } 我从MSDN文档找到了一个完美的解决方案。现在您可以这样编码: 首先,创建标签并使用此代码: <Label x:Name="MenuLabel" StyleClass="LabelStyle1" Text="RightClickMenu"> <FlyoutBase.ContextFlyout> <MenuFlyout> <MenuFlyoutItem Text="Back" Command="{Binding BackCommand}" > <MenuFlyoutItem.KeyboardAccelerators> <KeyboardAccelerator Modifiers="None" Key="Left" /> </MenuFlyoutItem.KeyboardAccelerators> </MenuFlyoutItem> <MenuFlyoutItem Text="Forward" Command="{Binding ForwardCommand}" > <MenuFlyoutItem.KeyboardAccelerators> <KeyboardAccelerator Modifiers="None" Key="Right" /> </MenuFlyoutItem.KeyboardAccelerators> </MenuFlyoutItem> <MenuFlyoutItem Text="GoToStart" Command="{Binding GoToStartCommand}" > <MenuFlyoutItem.KeyboardAccelerators> <KeyboardAccelerator Modifiers="None" Key="Up" /> </MenuFlyoutItem.KeyboardAccelerators> </MenuFlyoutItem> <MenuFlyoutItem Text="GoToEnd" Command="{Binding GoToEndCommand}" > <MenuFlyoutItem.KeyboardAccelerators> <KeyboardAccelerator Modifiers="None" Key="Down" /> </MenuFlyoutItem.KeyboardAccelerators> </MenuFlyoutItem> </MenuFlyout> </FlyoutBase.ContextFlyout> </Label> 秒,隐藏标签。 现在,您有键盘事件。 太简单了。 注意!该方法仅在.NET Core 8中可用。 运气好 如果您想了解更多,您会阅读 https://learn.microsoft.com/en-us/dotnet/maui/user-interface/keyboard-accelerators?view = net-maui-8.0 谢谢你!
在对此Quesiton进行重大编辑后,我希望现在很清楚。 当1个更改应影响多个属性时,我在WPF中的绑定非常失去。 我定期使用vvm将视图模型绑定到我的...
关注Apple关于组件的文档,我认为我理解了基本思想。 组件是捕获实体状态并可以通过系统操纵的对象。 到目前为止都很好,...
A组件是一个捕获实体状态并可以通过系统操纵的对象。
<TextBox BorderThickness="1" Style="{DynamicResource TextBoxInError}" Validation.ErrorTemplate="{StaticResource ValidationTemplate}"> <TextBox.Text> <Binding Path="TimeBeforeDeletingPicture" Mode="TwoWay"> <Binding.ValidationRules> <helpers:TimeBeforeDeletingRule/> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> 当我离开文本框时,验证会触发(显然是在失去焦点时),我想在每次更改文本时验证输入,我使用MVVM干净的方法来实现这一目标。 SETUPDATESOURCETRIGGER如下 <TextBox.Text> <Binding Path="TimeBeforeDeletingPicture" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/> 我知道这是旧帖子,但也许它仍然可以帮助某人。 toby默认值,UpdatesOulCetrigger=对于文本框控件而言,LostFocus。这就是为什么验证仅在那时触发的原因。当然,您可以更改为updatesourcetrigger=propertyChanged。但是,您可能需要在输入时验证并应用错误模板,但仅在丢失焦点时才更新源模型属性。无论如何我都需要这个。 这是您可以在不更新源的情况下验证文本框的方式,该源是在文本交换器上验证的: internal void mytextbox_TextChanged(object sender, TextChangedEventArgs e) { TextBox txtBox = sender as TextBox; BindingExpression bindingExpression = BindingOperations.GetBindingExpression(txtBox, TextBox.TextProperty); if (!IsMyTextBoxValid(((TextBox)sender).Text)) { BindingExpressionBase bindingExpressionBase = BindingOperations.GetBindingExpressionBase(txtBox, TextBox.TextProperty); ValidationError validationError = new ValidationError(new ExceptionValidationRule(), bindingExpression); validationError.ErrorContent = "This value is not valid for my textbox"; Validation.MarkInvalid(bindingExpressionBase, validationError); } else Validation.ClearInvalid(bindingExpression); }
我每次添加/删除在Firebase中添加/删除项目的操作完成时都需要显示一条消息。这些是接口中的功能: 暂停娱乐添加节(项目:项目):响应 我每次添加/删除在Firebase中添加/删除项目的操作完成时都需要显示一条消息。这些是接口中的功能: suspend fun addItem(item: Item): Response<Unit> suspend fun deleteItem(item: Item): Response<Unit> 这些是实现: override suspend fun addItem(item: Item) = try { itemsRef.add(item).await() Response.Success(Unit) } catch (ex: Exception) { Response.Failure(ex) } override suspend fun deleteItem(item: Item) = try { itemsRef.document(item.id).delete().await() Response.Success(Unit) } catch (ex: Exception) { Response.Failure(ex) } 在ViewModel中,我称为addItem并重置这样的操作状态: class ItemViewModel @Inject constructor( private val repo: ItemRepository ): ViewModel() { private val _addItemResponse = MutableStateFlow<Response<String>?>(null) val addItemResponse: StateFlow<Response<String>?> = _addItemResponse.asStateFlow() private val _deleteItemResponse = MutableStateFlow<Response<String>?>(null) val deleteItemResponse: StateFlow<Response<String>?> = _deleteItemResponse.asStateFlow() fun addItem(item: Item) = viewModelScope.launch { _addItemResponse.value = Response.Loading _addItemResponse.value = repo.addItem(item) } fun deleteItem(item: Item) = viewModelScope.launch { _deleteItemResponse.value = Response.Loading _deleteItemResponse.value = repo.addItem(item) } fun resetAddItemState() = _addItemResponse.value?.let { _addItemResponse.value = null } fun resetDeleteItemState() = _deleteItemResponse.value?.let { _deleteItemResponse.value = null } } 在UI内部我使用: when(val addItemResponse = viewModel.addItemResponse.collectAsStateWithLifecycle().value) { is Response.Loading -> CircularProgressIndicator() is Response.Success -> { Toast.makeText(context, "Added", Toast.LENGTH_LONG).show() resetAddItemState() } is Response.Failure -> Text(addItemResponse.ex) } when(val deleteItemResponse = viewModel.deleteItemResponse.collectAsStateWithLifecycle().value) { is Response.Loading -> CircularProgressIndicator() is Response.Success -> { Toast.makeText(context, "Deleted", Toast.LENGTH_LONG).show() resetDeleteItemState() } is Response.Failure -> Text(deleteItemResponse.ex) } 当我添加一个项目时,显示第一个吐司。如果我删除项目并等待第二个吐司消失,则正确显示第二个吐司。但是,如果我添加一个项目并立即将其删除而不等待第一个吐司消失,则会显示第二个吐司。如何解决这个问题? 尝试使用应用程序context toast.maketext(applicationContext,“ message”,toast.length_short).show() 希望它会起作用。
我只有在完成壁炉中添加项目的操作完成时才需要显示一条消息。 这是接口中的功能: 暂停娱乐添加节(项目:项目):响应 这个...
我只有在完成壁炉中添加项目的操作完成时才需要显示一条消息。 这是接口中的功能: 暂停娱乐添加节(项目:项目):响应 这个...
我有一组集合。他们中的每个人都包含一系列单词。那么,如何在视图中绑定它们?
您没有本地DB。然后在整个应用程序中使用多个用户列表来提出其他网络请求,因此,只要App Live live life live并仅按需重新提取它,您肯定希望将其缓存。这一定意味着您要在我的情况下将其缓存在
IM在Android应用程序中使用MVVVM Architecthure使用干净的代码,并具有3层 UI->域 - >数据(存储库 - >数据源) 从我的数据层我想返回一个域obje ...