2014-10-01 2 views
0

Я работаю над Silverlight 5 существующим приложением, к которому подходит MVVM.Как использовать childwindow в этом случае

Я создал свой собственный ErrorMessageBox.xaml (childwindow) в папке View, и я в ситуации, когда этот ErrorMessageBox должен быть включен в класс внутри папки Model.

И я обнаружил, что ErrorMessageBox недоступен в Model (потому что он находится в папке View). Поэтому наконец я создал еще одну ErrorMessageBox.xaml внутри модели, чтобы она использовалась во всех классах в папке Model.

И когда я пытаюсь всплывать это дочернее окно (ErrorMessageBox.xaml), то оно не появляется. Почему это происходит и как всплывать этот ErrorMessageBox.xaml внутри вызова функции в классе в папке Model .

public static void ThisFunctionIsCalledIHaveVerifiedOnDebugging(string message) //it is inside a class in Model folder 
{ 
    ConfirmationWindow cfw = new ConfirmationWindow(); 
    cfw.SetMessage("Popup test"); 
    cfw.Show(); //it do not pop up it 
} 

И ConfirmationWindow.xaml является:

<silvercontrols:ChildWindow x:Class="Model.MessageFolder.ConfirmationWindow" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:silvercontrols="clr-namespace:Silverlight.Windows.Controls;assembly=Silverlight.Windows.Controls" 
      xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" 
      xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" 
      Title="Message" Width="Auto" Height="Auto" MouseRightButtonDown="ChildWindow_MouseRightButtonDown"> 

    <silvercontrols:ChildWindow.Style> 
     <StaticResource ResourceKey="MessageBoxStyle"/> 
    </silvercontrols:ChildWindow.Style> 

    <Grid x:Name="LayoutRoot" MinWidth="360"> 
     <StackPanel Orientation="Vertical"> 
      <TextBlock x:Name="MessageBox" Margin="10 15 0 0" Height="Auto" FontSize="12" Text="Text" Foreground="White" TextWrapping="Wrap" HorizontalAlignment="Left" /> 
      <StackPanel x:Name="ContentBox" Margin="10 15 0 0" Height="Auto" Orientation="Horizontal"></StackPanel> 
      <StackPanel Margin="0 0 0 10" Orientation="Horizontal" HorizontalAlignment="Center" Height="45"> 
       <Button x:Name="YesBtn" Content="Yes" Width="82" HorizontalAlignment="Left" VerticalAlignment="Bottom" Style="{StaticResource ButtonStyle_Blue}"/> 
       <Button x:Name="NoBtn" Content="No" Margin="60 0 0 0" Width="82" HorizontalAlignment="Right" VerticalAlignment="Bottom" Style="{StaticResource ButtonStyle_Blue}"/> 
      </StackPanel> 
     </StackPanel> 
    </Grid> 
</silvercontrols:ChildWindow> 

и ConfirmationWindow.xaml.cs является:

using System.Windows; 
namespace Model.MessageFolder 
{ 
    public partial class ConfirmationWindow : Silverlight.Windows.Controls.ChildWindow 
    { 
     private bool showBtnClose; 
     public ConfirmationWindow(bool showBtnClose = false) 
     { 
      InitializeComponent(); 
      HasCloseButton = showBtnClose; 
      this.showBtnClose = showBtnClose; 
      NoBtn.Click += Close; 
     } 

     #region METHODS 
     public void SetMessage(string message) 
     { 
      MessageBox.Text = message; 
     } 
     public void AddContent(UIElement elt) 
     { 
      ContentBox.Children.Add(elt); 
     } 
     #endregion 

     #region EVENT_HANDLER 
     public void Close(object sender, RoutedEventArgs e) 
     { 
      this.Close(); 
     } 
     #endregion 

     private void ChildWindow_MouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) 
     { 
      e.Handled = true; 
     } 
    } 
} 

Почему он не работает? Как заставить его работать?

+0

Вы пробовали с Dispatcher.BeginInvoke(), а также попытались привести CFW к фронту, используя istopmost = true – user2526236

ответ

1

Прежде всего, вы не должны приводить свой класс childwindow в папку моделей, так как он разбивает шаблон MVVM. Вместо этого оставьте это в своей папке просмотра. Что вы должны сделать, так это показать дочернее окно с точки зрения вашей модели. Чтобы достичь этого, вам нужно указать, как показывать свое представление, когда показывать дочернее окно и какое сообщение оно должно отображаться.

Во-первых, в модели создать свойство ErrorMessage:

public class MyModel : INotifyPropertyChanged 

{ ...

private string _errorMessage; 
public string ErrorMessage 
    { 
     private set 
     { 
      _errorMessage = value; 
      OnPropertyChanged("ErrorMessage"); 
     } 
     get { return _errorMessage;; } 
    } 

... }

Примечание: Здесь я предполагаю, что ваша модель класс реализует интерфейс INotifyPropertyChanged, но это может быть другая реализация.

Затем в коде вашего представления добавьте свойство зависимости и привяжите его к ErrorMessage вашей модели. Обратный вызов изменения свойства зависимостей используется для отображения дочернего окна. Это может выглядеть следующим образом:

public partial class MyView : UserControl 

{ ...

public static readonly DependencyProperty ErrorMessageProperty = 
     DependencyProperty.Register("ErrorMessage", typeof (string), typeof (MyView), 
       new PropertyMetadata((o, args) => 
       { 
        // Display childwindow when message is changed 
        string message = args.NewValue as string; 
        if(message!=null) 
        { 
          ConfirmationWindow cfw = new ConfirmationWindow(); 
          cfw.SetMessage(message); 
          cfw.Show(); 
        } 
       })); 

    public string ErrorMessage 
    { 
     get { return (string)GetValue(ErrorMessageProperty); } 
     private set { SetValue(ErrorMessageProperty, value); } 
    } 

...

public MyModel ViewModel 
    { 
... 
     set 
     { 
      DataContext = value;     

      Binding binding = new Binding(); 
      binding.Source = value; 
      binding.Path = new PropertyPath("ErrorMessage"); 
      SetBinding(ErrorMessageProperty, binding); 
     } 
    ... 
    } 

... }

Тогда каждый раз, когда вы измените значение ErrorMessage в своей модели, он должен показать chil dwindow.

Смежные вопросы