UWP ContentDialog调用

Dmy*_*tro 6 modal-dialog mvvm winrt-xaml uwp template10

我正在使用UWP和Template 10通过遵循MVVM模式来构建GUI应用程序.作为应用程序的一部分,我需要通过按主页面上的按钮来调用内容对话框.因此,为独立的.xaml文件创建了单独的ContentDialog:

<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>
Run Code Online (Sandbox Code Playgroud)

通过按下按钮在主页面中打开/调用它的正确方法是什么(因为我需要为视图和视图模型保持逻辑分离)?

我现在怎么做:

从主页面我调用DictateCommand,它又创建一个ContentDialog实例并显示它:

 <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();
        }
Run Code Online (Sandbox Code Playgroud)

对我来说,它看起来像MVVM模式.能帮助我以正确的方式做到吗?

编辑:

我已经实现了对话服务并将其注入主视图模型中.但是,我遇到了另一个障碍.对于此对话框,我创建了单独的视图模型和属性,它封装了对话框文本框值.当我按下对话框上的"接受"按钮时 - 我需要将此值反映在我的主视图上.所以我需要将对话框的视图模型中的对话框文本框值传递给主视图模型.我应该执行另一个依赖注入来处理它吗?

Jer*_*xon 11

你有四个选择.

ONE第一个是服务,就像@ Ask-too-much-explain.事实上,如果你喜欢它,这是一个很好的解决方案.

第一种解决方案的好处是它可以重复使用.如果您没有重复使用此UI,说实话,专用服务可能会过度.

TWO第二个是视图模型事件.也就是说,您的Page可以订阅您的视图模型的事件(让我们称之为ShowContentDialog),当它被视图模型引发时,您的Page会处理它的表示.

这种方法的好处是,就像第一种方法一样,你将努力转移到另一个类.在这种情况下,您正在创建可能是一次性解决方案而无需服务,服务接口或以某种方式注入该服务.如果你不等待事件的结果,那么我认为这是99%像你这样的问题的想法.

.第三种方法是使用可以绑定到属性的不同控件.例如,由于您已在使用模板10,因此可以使用具有IsModal属性的ModalDialog控件.视图模型中的属性(让我们称之为IsModalVisible)可用于控制对话框而不与其耦合.

这很好的部分是你可以从视图模型的逻辑中调用对话框,就像前两种方法一样.但与第一个不同,您不需要服务.与第二个不同,您不需要处理程序.这是最"数据绑定"的方式,而且可能是我会做的.

第四种方式来做到这一点是使用消息.消息传递是视图模型用于与另一个视图模型通信的机制.在这种情况下,您可以使用来自您的视图模型(我们可能称之为ShowDialog的消息)的消息,而不是在另一个视图模型中,而是在您的Page中.这也可以.

这方面的缺点是您需要一个消息传递解决方案,但您可能已经拥有它.从好的方面来说,处理视觉的逻辑可以随时重新定位,因为Messaging会被任何人监听.

如果我是你,我可能会先考虑3号.如果不了解您的应用场景,我无法确定.不过,您是开发人员.所有这四个选项都很好.请确保不要试图将UIElement传递给您的视图模型.这是不必要的肮脏:)

祝你好运!


Ask*_*uch 5

MVVM中的建议解决方案是不要Speech Dialog在ViewModel中创建直接创建实例SpeechDialogService.

public interface ISpeechDialogService
{
    Task ShowAsync();
}

public class SpeechDialogService : ISpeechDialogService
{
    public async Task ShowAsync()
    {
        var contentDialog = new Speech();
        await contentDialog.ShowAsync();

    }
}
Run Code Online (Sandbox Code Playgroud)

并在您的ViewModel构造函数中注入此服务

public class AbcViewModel
{
    readonly ISpeechDialogService _dialog;

    public AbcViewModel(ISpeechDialogService dialog)
    {
        _dialog = dialog;
    }

    public async void Dictate(object obj)
    {
        await _dialog.ShowAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)