• Prism框架 如何在主程序中合理的弹出子窗体


    说起子窗体,大家都会想到ChildWindow,多熟悉的一个控件。不错,Sliverlight中已经提供了子窗体的具体实现,而在WPF中却没有这么好的事情(有的第三方控件商已经提供此控件)。最常见的实现方法就是在ViewModel中,直接New ChildWindow,然后直接Show。这样的方法也达到的要求。但是它不符合MVVM分层思想,再就是代码不美观,难以维护,今天我就给大家介绍一种美观又实用的方法。

    通过Prism中提供的InteractionRequestTrigger事件触发器,实现点击按钮或者用户的某种操作弹出对话框的效果。另外,不要忘了引用此命名空间:

    using Microsoft.Practices.Prism.Interactivity.InteractionRequest;
    <Window x:Class="ChildWindowDemo.ChildWindow.ChildWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"  
            xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
            Width="300" Height="150" 
            Title="{Binding Title}"
            x:Name="confirmationWindow" Topmost="True" WindowStyle="ToolWindow" WindowStartupLocation="CenterScreen">
        <Grid x:Name="LayoutRoot" Margin="2">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
            <ContentControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Content="{Binding Content}"/>
    
            <Button Content="Cancel" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,0,0" Grid.Row="1">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <ei:CallMethodAction TargetObject="{Binding ElementName=confirmationWindow}" MethodName="Close"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
            <Button Content="OK" Width="75" Height="23" HorizontalAlignment="Right" Margin="0,12,79,0" Grid.Row="1">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <ei:ChangePropertyAction PropertyName="Confirmed" TargetObject="{Binding}" Value="True"/>
                        <ei:CallMethodAction TargetObject="{Binding ElementName=confirmationWindow}" MethodName="Close"/>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </Button>
        </Grid>
    </Window>

    创建ChildWindow的基类

    新建类:ChildWindowActionBase 并从TriggerAction<T>派生,代码如下:

    public class ChildWindowActionBase : TriggerAction<FrameworkElement>
        {
            protected override void Invoke(object parameter)
            {
                var arg = parameter as InteractionRequestedEventArgs;
                if (arg == null)
                    return;
    
                var windows = this.GetChildWindow(arg.Context);
    
                var callback = arg.Callback;
                EventHandler handler = null;
                handler =
                    (o, e) =>
                    {
                        windows.Closed -= handler;
                        callback();
                    };
                windows.Closed += handler;
    
                windows.ShowDialog();
    
            }
    
            Window GetChildWindow(Notification notification)
            {
                var childWindow = this.CreateDefaultWindow(notification);
                childWindow.DataContext = notification;
    
                return childWindow;
            }
    
            Window CreateDefaultWindow(Notification notification)
            {
                return (Window)new ChildWindow.ChildWindow();
            }
        }

    到此子窗体已经完成

    <Window x:Class="ChildWindowDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:prism="http://www.codeplex.com/prism"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:local="clr-namespace:ChildWindowDemo"
            Title="MainWindow" Height="200" Width="300">
        <i:Interaction.Triggers>
            <prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest, Mode=OneWay}">
                <local:ChildWindowActionBase/>
            </prism:InteractionRequestTrigger>
        </i:Interaction.Triggers>
        <Grid>
            <Button Command="{Binding RaiseConfirmation}" Content="Click Me !" HorizontalAlignment="Left" Margin="29,31,0,0" VerticalAlignment="Top" Width="217" Height="55"/>
            <TextBlock HorizontalAlignment="Left" Margin="29,106,0,0" TextWrapping="Wrap" Text="{Binding ConfirmationResult}" VerticalAlignment="Top"/>
        </Grid>
    </Window>

    对之对应的ViewModel:

    public class MainWindowViewModel : NotificationObject
        {
            public MainWindowViewModel()
            {
                this.RaiseConfirmation = new DelegateCommand(this.OnRaiseConfirmation);
                this.ConfirmationRequest = new InteractionRequest<Confirmation>();
            }
    
            public InteractionRequest<Confirmation> ConfirmationRequest { get; private set; }
    
            public DelegateCommand RaiseConfirmation { get; private set; }
    
            private string result;
            public string ConfirmationResult
            {
                get { return result; }
                set
                {
                    result = value;
                    this.RaisePropertyChanged(() => this.ConfirmationResult);
                }
            }
    
            private void OnRaiseConfirmation()
            {
                this.ConfirmationRequest.Raise(
                    new Confirmation { Content = "是否确认", Title = "子窗体" },
                    (cb) => { ConfirmationResult = cb.Confirmed ? "确认" : "取消"; });
            }      
        }

    这样的写法比较符合MVVM的分层思想,子窗体可以随心定制,而不需要去改逻辑层的代码。

    http://www.cnblogs.com/sunthx/p/3539900.html

  • 相关阅读:
    github添加ssh
    包围盒的计算以及物体移动到世界坐标中心
    123
    mysql
    建站步骤
    深度遍历和广度遍历
    Js特殊字符转义之htmlEscape()方法
    参数命名风格转换
    http 206
    js 实现快速排序
  • 原文地址:https://www.cnblogs.com/tianciliangen/p/4961045.html
Copyright © 2020-2023  润新知