Search This Blog

Wednesday, August 31, 2011

Show PRISM message box; Display message box using PRISM MVVM Silverlight

We want to display a message box with the help of PRISM in Silverlight.
There is a different class for displaying an question - Confirmation. We
can display our own window with InteractionRequest<OurViewModel> and some code in XAML
defining which view to run.


Message box class in defined in PRISM's namespace:
namespace: Microsoft.Practices.Prism.Interactivity.InteractionRequest

Class name is Notification.

SomeView, XAML:

<UserControl x:Class="WebClient.SomeView"
..... >

    <Grid x:Name="LayoutRoot" Background="White">
        <i:Interaction.Triggers>
            <prism:InteractionRequestTrigger SourceObject="{Binding SaveNotification}">
                <prism:PopupChildWindowAction/>
            </prism:InteractionRequestTrigger>
        </i:Interaction.Triggers>
    </Grid>
</UserControl>

SomeViewModel, cs:

public class SomeViewModel
{
    public SomeViewModel(......)
    {
        saveNotification = new InteractionRequest<Notification>();
    }

    private readonly InteractionRequest<Notification> saveNotification;

    //this function displays message box
    private void someFunction(object obj)
    {
        //show message box
        ((InteractionRequest<Notification>)saveNotification).Raise(new Notification { Title = "Information", Content = "User was saved." });           
    }

    public IInteractionRequest SaveNotification
    {
        get { return this.saveNotification; }
    }
}

Set property in View from ViewModel in MVVM using Interaction Triggers; Set View's property from ViewModel without code behind in Silverlight 4.0

We have a View which is a Window control with DialogResult property and we want to set this property to True without using code behind.

<controls:ChildWindow  x:Class="WebClient.Views.ConfWorkerView"

   xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
   xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
   xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions”
Name="Window" >

  <UserControl>
    <Grid>
    <Button HorizontalAlignment="Right" Content="Save"  Command="{Binding SaveCommand}" >
          <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
               <ei:ChangePropertyAction PropertyName="DialogResult" Value="True" TargetName="Window"/>
            </i:EventTrigger>
          </i:Interaction.Triggers>
       </Button>
    <Grid>
  <UserControl>
</controls:ChildWindow>

Tuesday, August 23, 2011

PRISM passing data in RegionContext

Define region in the following way - with regionName and region context defined

xmlns:regions="clr-namespace:Microsoft.Practices.Prism.Regions;assembly=Microsoft.Practices.Prism"

<ItemsControl MinHeight="400" regions:RegionManager.RegionName="RCP.WorkerShowPersonalDataRegion" regions:RegionManager.RegionContext="{Binding Path=CurrentWorker, Mode=TwoWay}" >
    <!-- PRISM registers various types of configuration views here -->
</ItemsControl>

 

Receive Context in ViewModel like this:
this.RegionContext = regionManager.Regions[RegionNames.WorkerShowPersonalDataRegion].Context;

This can be done in Constructor or e.g. OnNavigatedTo method from PRISM INavigationAware.

PRISM region in ItemsControl, Region.RegionContext is null when deleting views from region

When you delete views from your region, the RegionContext is set to null. This is probably done to
prevent memory leaks but is really frustrating at the beginning. To prevent RegionContext from being
deleted you have two options:
1) use <ContentControl as your region control. In this solution views will be replace and you won't have to delete view from region thus preventing RegionContext from being nulled
2) Clone the object that you set as RegionContext (not really a neat solution)

//delete views from your region
IViewsCollection views = regionManager.Regions[RegionNames.WorkerShowPersonalDataRegion].Views;
int count = views.Count();
foreach (var view in views)
{
    regionManager.Regions[RegionNames.WorkerShowPersonalDataRegion].Remove(view);
}
regionManager.Regions[RegionNames.WorkerShowPersonalDataRegion].Context = new Worker(CurrentWorker);