UWP ContentDialog 调用 [英] UWP ContentDialog Invocation
问题描述
我正在使用 UWP 和模板 10 按照 MVVM 模式构建 GUI 应用程序.作为应用程序的一部分,我需要通过按下主页上的按钮来调用内容对话框.为此,在独立的 .xaml 文件中创建了单独的 ContentDialog:
I am using UWP and Template 10 to build a GUI app by following MVVM pattern. As a part of application I need to invoke a content dialog by pressing button on Main Page. So separate ContentDialog was created in standalone .xaml file for that purpose:
<ContentDialog
x:Class="UWP1.Views.Speech"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWP1.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="Dictate"
PrimaryButtonText="Accept"
SecondaryButtonText="Cancel"
PrimaryButtonClick="ContentDialog_PrimaryButtonClick"
SecondaryButtonClick="ContentDialog_SecondaryButtonClick"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<Button Margin="15" Content="Dictate" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch"/>
<Button Margin="15" Content="Clear Text" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch"/>
<TextBlock Grid.Row="1" Grid.ColumnSpan="2" Text="Tap 'Dictate', and speak" FontSize="12" />
<TextBlock Margin="0 10 0 0" Grid.Row="2" Grid.ColumnSpan="2" Text="Message Dication" HorizontalAlignment="Center" FontSize="24" />
<ScrollViewer Grid.Row="3" Grid.ColumnSpan="2" Height="300">
<TextBox Margin="5 5 5 10" AcceptsReturn="True" />
</ScrollViewer>
</Grid>
</ContentDialog>
按下按钮在我的主页中打开/调用它的正确方法是什么(因为我需要保持视图和视图模型的逻辑分离)?
What is the proper way to open/invoke it in my Main Page by pressing button (as I need to keep logic separated for view and viewmodel)?
我现在的做法:
我从主页调用 DictateCommand,它依次创建一个 ContentDialog 实例并显示它:
From Main Page I invoke DictateCommand, which in turn creates an instance of ContentDialog and shows it:
<AppBarButton Grid.Column="1" Icon="Microphone" IsCompact="True" HorizontalAlignment="Right" Command="{Binding DictateCommand}"/>
public ICommand DictateCommand { get; set; }
public async void Dictate(object obj)
{
var contentDialog = new Speech();
await contentDialog.ShowAsync();
}
对我来说,这看起来像是违反了 MVVM 模式.你能帮我以正确的方式做吗?
It looks like a MVVM pattern breach for me. Could you please help me to do it in a right way?
我已经实现了对话服务并将其注入到主视图模型中.然而,我遇到了另一个障碍.对于这个对话框,我创建了单独的视图模型和属性,它封装了对话框文本框的值.当我按下对话框上的接受"按钮时 - 我需要将此值反映在我的主视图中.所以我需要将对话框的文本框值从对话框的视图模型传递到主视图模型.我应该执行另一个依赖注入来处理它吗?
I have implemented dialog service and injected it in the main view model. However, I got another obstacle. For this dialog I created separate view model and property which encapsulates dialog text box value. When I press 'accept' button on the dialog - I need this value to be reflected on my Main View. So I need to pass dialog's text box value from dialog's view model to main view model. Should I perform another dependency injection to deal with it?
推荐答案
您有四个选项.
ONE 第一个是服务,就像@Ask-too-much 解释的那样.事实上,如果您喜欢,这是一个很好的解决方案.
ONE The first is a service, just like @Ask-too-much explains. In fact, this is a beautiful solution if you like it.
第一个解决方案的好处是它是可重用的.如果你不重用这个 UI,老实说,一个专门的服务可能有点矫枉过正.
The benefits of the first solution are that it is reusable. If you are not reusing this UI, a dedicated service might be overkill, to be honest.
两个 第二个是视图模型事件.也就是说,你的页面可以订阅你的视图模型的事件(我们称之为 ShowContentDialog),当它被视图模型引发时,你的页面处理它的呈现.
TWO The second is a view-model event. That is to say, your Page can subscribe to your view-model's event (let's call it ShowContentDialog) and when it is raised by the view-model, your Page handle its presentation.
这种方法的好处是,就像第一种方法一样,您可以将工作转移到另一个类.在这种情况下,您正在创建可能是一次性的解决方案,而无需服务、服务接口或以某种方式注入该服务.如果您不是在等待事件的结果,那么我认为这适用于 99% 的问题.
The benefits this approach is that, just like the first approach, you are offloading the effort to another class. In this case, you are creating what is likely a one-off solution without needing a service, a service interface, or injection of that service somehow. If you are not waiting for the result of the event, then I think this is idea for 99% of issues like yours.
三种 第三种方法是使用可以绑定到属性的不同控件.例如,由于您已经在使用模板 10,您可以使用具有 IsModal 属性的 ModalDialog 控件.视图模型中的一个属性(我们称之为 IsModalVisible)可用于控制对话框而无需与其耦合.
THREE The third approach is to use a different control that can be bound to a property. For example, since you are already using Template 10, you can use the ModalDialog control which has an IsModal property. A property in your view-model (let's call it IsModalVisible) can be used to control the dialog without coupling to it.
这样做的好处是您可以从视图模型的逻辑中调用对话框,就像前两种方法一样.但与第一个不同的是,您不需要服务.与第二个不同,您不需要处理程序.这是最数据绑定"的方式,可能也是我会做的.
The good part of this is that you get to invoke the dialog from the logic of your view-model, just like the first two approaches. But unlike the first, you do not need a service. Unlike the second, you do not need a handler. It's the most "data binding" way to do it, and likely what I would do.
四种第四种方法是使用消息传递.消息传递是一个视图模型用来与另一个视图模型进行通信的机制.在这种情况下,您可以使用来自您的视图模型(带有我们可能称为 ShowDialog 的消息)的消息,该消息被监听,而不是在另一个视图模型中,而是在您的页面中.这也能正常工作.
FOUR The fourth way to do it is to use messaging. Messaging is the mechanism one view-model uses to communicate with another. IN this case you could use messaging from your view-model (with a message we might call ShowDialog) that is listened for, not in another view-model, but in your Page. This would work fine, too.
这样做的缺点是您需要一个消息传递解决方案,但您可能已经拥有了.好处是处理视觉的逻辑可以随时重新定位,因为消息被多播给任何收听的人.
The down side to this is that you need a messaging solution, but you might already have that. The up-side is that the logic for handling the visual could be relocated at any time as Messaging is multicasted to anyone listening.
如果我是你,我可能会先考虑 3 号.如果对您的应用场景没有更多了解,我无法确定.不过,您是开发人员.这四个选项都不错.请确保不要试图将 UIElement 传递到您的视图模型中.这是不必要的肮脏:)
If I were you, I would consider number 3 first, perhaps. Without a little more understanding of your app scenario, I can't be sure. You are a developer, though. All four of those options are good. Just be sure not to be tempted into passing the UIElement into your view-model. That's needless nastiness :)
祝你好运!
这篇关于UWP ContentDialog 调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!