Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
294 views
in Technique[技术] by (71.8m points)

c# - Prism pop-up new window in WPF

How can I open/close a new window in WPF without violating rules of the MVVM pattern?
I just want to mimic the login module of ms office outlook.

I've already read this article, but there are an error in passing a parameter confirmation

I'm currently using prism 5.0.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Luckily, Prism 5.0 (and I assume 6.0 too, haven't worked with it yet), has a class called InteractionRequest<T> which you can use from code to raise interaction requests.

An interaction request is basically a window, that asks the user for a certain action and calls a callback (if necessary or desired) with the users decisions/actions.

public class ShellViewModel : BindableBase
{
    private readonly IRegionManager regionManager;

    public ShellViewModel(IRegionManager regionManager)
    {
        if (regionManager == null)
            throw new ArgumentNullException("regionManager");

        this.regionManager = regionManager;
        this.OptionSettingConfirmationRequest = new InteractionRequest<IConfirmation>();

        openConnectionOptionsCommand = new DelegateCommand(RaiseConnectionOptionsRequest);
    }

    public InteractionRequest<IConfirmation> OptionSettingConfirmationRequest { get; private set; }

    private readonly ICommand openConnectionOptionsCommand;
    public ICommand OpenConnectionOptionsCommand { get { return openConnectionOptionsCommand; } }

    private void RaiseConnectionOptionsRequest()
    {
        this.OptionSettingConfirmationRequest.Raise(new Confirmation { Title = "Options not saved. Do you wish to save?" }, OnConnectionOptionsResponse);
    }

    protected virtual void OnConnectionOptionsResponse(IConfirmation context)
    {
        if(context.Confirmed)
        {
            // save it
        }

        // otherwise do nothing
    }
}

In XAML you would do something like

<Button Content="Options" Command="{Binding OpenConnectionOptionsCommand}">
    <i:Interaction.Triggers>
        <pit:InteractionRequestTrigger SourceObject="{Binding OptionSettingConfirmationRequest, Mode=OneWay}" >
            <pie:LazyPopupWindowAction RegionName="ConnectionSettings" 
                                NavigationUri="ConnectionSettingsView" IsModal="True" />
        </pit:InteractionRequestTrigger>
    </i:Interaction.Triggers>
</Button>

I used my own implemetation of PopupWindowAction (see github project page for it's implementation) called LazyPopupWindowAction, which will instantiate the embedded ConnectionSettingsView View on click. If you don't care that your view is instantiated only once, feel free to use PopupWindowAction, then it will be instantiated at the same time as the View containing the action.

It's basically copy & paste with cutting some useless lines from one of my projects. I used IConfirmation and INotification interfaces instead of the concrete implementations.

XAML with PopupWindowAction

<Button Content="Options" Command="{Binding OpenConnectionOptionsCommand}">
    <i:Interaction.Triggers>
        <pit:InteractionRequestTrigger SourceObject="{Binding OptionSettingConfirmationRequest, Mode=OneWay}" >
            <pi:PopupWindowAction>
                <pi:PopupWindowAction.WindowContent>
                    <views:CustomPopupView />
                </pi:PopupWindowAction.WindowContent>
            </pi:PopupWindowAction>
        </pit:InteractionRequestTrigger>
    </i:Interaction.Triggers>
</Button>

Namespace declarations

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:pi="clr-namespace:Microsoft.Practices.Prism.Interactivity;assembly=Microsoft.Practices.Prism.Interactivity"
xmlns:pit="clr-namespace:Microsoft.Practices.Prism.Interactivity.InteractionRequest;assembly=Microsoft.Practices.Prism.Interactivity"
xmlns:pie="clr-namespace:MyProject.UI.Prism.Interactivity;assembly=MyProject.UI"

Update: Since people keep asking about the LazyPopupWindowAction, I've put the source in a GitHub Gist. Basically it's based on the PopupWindowAction from Prims 5 (and for Prism, haven't test it with Prism 6 yet, probably won't work w/o adjustments) and does the exact same thing, but also adds Region and Navigation support with the opened window, something that I needed in my application.

One thing I disliked about the default implementation was, that the view and it's viewmodel will be instantiated at the same time the Shell gets instantiated and the ViewModel remains in it's state, when you close it (it was actually just hidden).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...