关闭View后,ViewModel仍然存在

时间:2011-11-21 12:54:20

标签: silverlight-4.0 mvvm-light messenger

我有一个用户控件(radwindow),该任务正在添加新项目。 我从父窗口调用此窗口,但是当我关闭此模态控件并再次调用它时,我看到viewmodel与之前相同,所以我控制了旧数据。 Ofcource我需要控制空字段:)

我正在使用MVVM Light。我知道它可能是Messenger的内容,但我没有看到我的代码有任何问题。

<telerik:RadWindow x:Class="MyAppApp.View.AddMessageTemplateView"
             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:telerik="http://schemas.telerik.com/2008/xaml/presentation"
                   xmlns:prismvm="clr-namespace:Microsoft.Practices.Prism.ViewModel;assembly=Microsoft.Practices.Prism"
                   xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
                   xmlns:Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
                   xmlns:Converters="clr-namespace:MyAppApp.Converters"

                   xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
                   xmlns:HTMLParsing="clr-namespace:MyAppApp.Helpers.HTMLParsing" mc:Ignorable="d"
             DataContext="{Binding AddMessageTemplate, Source={StaticResource Locator}}"  d:DesignHeight="300" d:DesignWidth="400" WindowStartupLocation="CenterScreen"
     ResizeMode="NoResize" Width="355" >
    <telerik:RadWindow.Resources>
        <Converters:RadioButtonConverter x:Key="RadioButtonConverter"/>
        <Converters:EnumsMatchToVisibilityConverter x:Key="EnumsMatchToVisibilityConverter"/>
    </telerik:RadWindow.Resources>
    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/>
            <RowDefinition Height="20"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <TextBlock Text="{Binding Path=MyAppResources.label_PleaseSelectTypeOfMessageTemplate, Source={StaticResource ResourcesWrapper}}"/>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <RadioButton Content="Email" Margin="0 0 10 0" 
  GroupName="MessageTypes" 
  IsChecked="{Binding SelectedType, Mode=TwoWay, ConverterParameter=Email, 
             Converter={StaticResource RadioButtonConverter}}" />

            <RadioButton Content="SMS" Margin="0 0 10 0" 
  GroupName="MessageTypes" 
  IsChecked="{Binding SelectedType, Mode=TwoWay, ConverterParameter=Sms, 
             Converter={StaticResource RadioButtonConverter}}" />
        </StackPanel>
        <!--Place for New Item> -->
        <StackPanel Grid.Row="2" HorizontalAlignment="Stretch">
            <Grid
    x:Name="DetailsGrid">
                <prismvm:DataTemplateSelector
        Content="{Binding NewTemplate}" HorizontalContentAlignment="Stretch">
                    <prismvm:DataTemplateSelector.Resources>
                        <DataTemplate
                x:Key="EmailMessageTemplate">
                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="{Binding Path=MyAppResources.label_NameOfMessageTemplate, Source={StaticResource ResourcesWrapper}}"/>
                                <TextBox Text="{Binding Name,Mode=TwoWay}" HorizontalAlignment="Stretch" />
                                <TextBlock Text="{Binding Path=MyAppResources.label_SubjectOfMessageTemplate, Source={StaticResource ResourcesWrapper}}"/>
                                <TextBox Text="{Binding EmailSubject,Mode=TwoWay}" HorizontalAlignment="Stretch"/>

                                <StackPanel Orientation="Vertical">
                                    <RadioButton Content="HTML" Margin="0 0 10 0" 
  GroupName="EmailFormat" 
  IsChecked="{Binding EmailFormat, Mode=TwoWay, ConverterParameter=HTML, 
             Converter={StaticResource RadioButtonConverter}}" />

                                    <RadioButton Content="Plain Text" Margin="0 0 10 0" 
  GroupName="EmailFormat" x:Name="PlainTextRadioButton" 
  IsChecked="{Binding EmailFormat, Mode=TwoWay, ConverterParameter=PlainText, 
             Converter={StaticResource RadioButtonConverter}}" />
                                </StackPanel>
                                <TextBlock Text="{Binding Path=MyAppResources.label_BodyOfMessageTemplate, Source={StaticResource ResourcesWrapper}}"/>

                                <ScrollViewer MaxHeight="100" HorizontalAlignment="Stretch" Margin="0,10,0,10" Name="scrollViewerEmailBody" VerticalAlignment="Top">
                                    <TextBox Text="{Binding Body,Mode=TwoWay}" TextWrapping="Wrap" AcceptsReturn="True" />
                                </ScrollViewer>

                                <ScrollViewer  HorizontalAlignment="Stretch" Margin="0,10,0,10" Name="scrollViewerEmail2RadHtmlPlaceholder" Visibility="{Binding EmailFormat,ConverterParameter=HTML,Converter={StaticResource  EnumsMatchToVisibilityConverter}}" >
                                    <HTMLParsing:HtmlTextBlock Html="{Binding Body}"/>
                                </ScrollViewer>
                            </StackPanel>

                        </DataTemplate>
                        <DataTemplate
                x:Key="SmsMessageTemplate">
                            <StackPanel Orientation="Vertical">
                                <TextBlock Text="{Binding Path=MyAppResources.label_NameOfMessageTemplate, Source={StaticResource ResourcesWrapper}}"/>
                                <TextBox Text="{Binding Name,Mode=TwoWay}" HorizontalAlignment="Stretch" />
                                <TextBlock Text="{Binding Path=MyAppResources.label_BodyOfMessageTemplate, Source={StaticResource ResourcesWrapper}}"/>

                                <ScrollViewer MaxHeight="100" HorizontalAlignment="Stretch" Margin="0,10,0,10"  VerticalAlignment="Top">
                                    <TextBox Text="{Binding Body,Mode=TwoWay}" TextWrapping="Wrap" AcceptsReturn="True" />
                                </ScrollViewer>
                            </StackPanel>
                        </DataTemplate>

                    </prismvm:DataTemplateSelector.Resources>
                </prismvm:DataTemplateSelector>
            </Grid>
        </StackPanel>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
              Grid.Row="3" Grid.Column="0">
            <telerik:RadButton x:Name="btnOK" Width="120" Content="{Binding Path=MyAppResources.OkSoeDialog, Source={StaticResource ResourcesWrapper}}"
                 Margin="5"  >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <Command:EventToCommand Command="{Binding Source={StaticResource Locator}, Path= AddMessageTemplate.SaveCommand}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </telerik:RadButton>
            <telerik:RadButton x:Name="btnCancel" Width="120" Content="{Binding Path=MyAppResources.CancelSoeDialog, Source={StaticResource ResourcesWrapper}}"
                 Margin="5"  >
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                        <Command:EventToCommand Command="{Binding Source={StaticResource Locator}, Path= AddMessageTemplate.CancelCommand}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>

            </telerik:RadButton>
        </StackPanel>
    </Grid>
</telerik:RadWindow>

以下是radwindow

背后的代码
 public partial class AddMessageTemplateView : RadWindow
    {
        /// <summary>
        /// Initializes a new instance of the AddMessageTemplateView class.
        /// </summary>
        public AddMessageTemplateView()
        {
            InitializeComponent();

            (this.DataContext as AddMessageTemplateViewModel).RequestClose += Close;
        }
    }



using System;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Telerik.Windows.Controls;
using MyAppUtils.DataModel;
using MyAppUtils.DataModel.Messaging;
using ViewModelBase = GalaSoft.MvvmLight.ViewModelBase;

namespace MyAppApp.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class AddMessageTemplateViewModel : ViewModelBase
    {
        private MessageTemplate _newTemplate;
        private MessageType _selectedtype;
        private string SelectedTypePropertyName = "SelectedType";
        private string NewTemplatePropertyName = "NewTemplate";

        /// <summary>
        /// Initializes a new instance of the AddMessageTemplateViewModel class.
        /// </summary>
        public AddMessageTemplateViewModel()
        {
            InitiateCommands();
            ////if (IsInDesignMode)
            ////{
            ////    // Code runs in Blend --> create design time data.
            ////}
            ////else
            ////{
            ////    // Code runs "for real": Connect to service, etc...
            ////}
        }

        public MessageTemplate NewTemplate
        {
            get { return _newTemplate; }


            set
            {
                if (_newTemplate != value)
                {
                    _newTemplate = value;
                    RaisePropertyChanged(NewTemplatePropertyName);
                }
            }
        }

        public void InitiateCommands()
        {

            SaveCommand = new RelayCommand(Save);
            CancelCommand = new RelayCommand(Cancel);
        }

        private void Cancel()
        {
            Messenger.Default.Send(new NotificationMessage(this, "Cancel"));
            Close();
        }

        private void Save()
        {
            //TODO: walidacja jak w customervehicle
            if (String.IsNullOrEmpty(NewTemplate.Error))
            {
                Messenger.Default.Send(new NotificationMessage<MessageTemplate>(this, NewTemplate, "Add"));
                Close();
            }
            else
            {
                RadWindow.Alert(NewTemplate.Error);
            }

        }

        public RelayCommand SaveCommand { get; private set; }
        public RelayCommand CancelCommand { get; private set; }

        public MessageType SelectedType
        {
            get { return _selectedtype; }
            set
            {
                if (_selectedtype != value)
                {
                    _selectedtype = value;
                    RaisePropertyChanged(SelectedTypePropertyName);
                    if (_selectedtype.ToString() == MessageType.Email.ToString())
                    {
                        NewTemplate = new EmailMessageTemplate();
                    }
                    else if (_selectedtype.ToString() == MessageType.Sms.ToString())
                    {
                        NewTemplate = new SmsMessageTemplate();
                    }
                    else
                    {
                        NewTemplate = null;
                    }
                }
            }
        }

        public event Action RequestClose;

        public virtual void Close()
        {
            if (RequestClose != null)
            {
                RequestClose();
            }
        }



    }
}

父控制代码的一部分

private void HandleNotification(NotificationMessage obj)
        {
            if (obj.Notification == "ShowAddMessageTemplate")
            {
                var ShowAddMessageTemplateRadWindow = new AddMessageTemplateView();
                ShowAddMessageTemplateRadWindow.Show();
            }
        }

父母控制的模型:

private void ShowAddMessageTemplate()
        {


            Messenger.Default.Send(new NotificationMessage(this, "ShowAddMessageTemplate"));


            Messenger.Default.Register<NotificationMessage<MessageTemplate>>(this, HandleMessageTemplateAdding);


        }

        private void HandleMessageTemplateAdding(NotificationMessage<MessageTemplate> notificationMessage)
        {

            if (notificationMessage.Notification=="Add")
            {
                ServiceAgent.AddMessageTemplate(notificationMessage.Content,_App.HandlerId,GetMessageTemplates);
            }

        }

1 个答案:

答案 0 :(得分:0)

我通过添加到AddMessageTemplateView的构造函数来解决这个问题:

this.Closed += (s, e) => ViewModelLocator.ClearAddMessageTemplate();

ClearAddMessageTemplateI是:

  public static void ClearAddMessageTemplate()
        {
            _addMessageTemplate.Cleanup();
            _addMessageTemplate = null;
        }