I am working on a silverlight 5 existing application where MVVM approached is followed.
我正在开发一个Silverlight 5现有应用程序,其中遵循MVVM接近。
I have created a my own ErrorMessageBox.xaml (childwindow) in View folder and i am in situation where this ErrorMessageBox must be popuped in a class inside Model folder.
我在View文件夹中创建了一个自己的ErrorMessageBox.xaml(childwindow),我遇到的情况是必须在Model文件夹中的类中填充此ErrorMessageBox。
And i found that the ErrorMessageBox are not accessible in Model (because it is in View folder).So at last i created one more ErrorMessageBox.xaml inside Model so that it will be used in all classes in Model folder.
我发现在Model中无法访问ErrorMessageBox(因为它在View文件夹中)。所以最后我在Model中创建了一个ErrorMessageBox.xaml,以便它将在Model文件夹中的所有类中使用。
And when i try to popup this child window(ErrorMessageBox.xaml) then it do not pop up. Why it happens and how to Pop up this ErrorMessageBox.xaml inside a function call in a class in Model folder.
当我尝试弹出这个子窗口(ErrorMessageBox.xaml)时,它不会弹出。为什么会发生这种情况以及如何在Model文件夹中的类中的函数调用中弹出此ErrorMessageBox.xaml。
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
}
And ConfirmationWindow.xaml is :
而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>
and ConfirmationWindow.xaml.cs is :
和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;
}
}
}
Why it is not working? How to make it work ?
为什么不工作?如何使其工作?
1 个解决方案
#1
1
First thing is that you should not bring your childwindow class in the models folder because it breaks the MVVM pattern. Instead leave it in your views folder. What you should do is to show the childwindow from your model's view. To achieve that you need a way to tell your view when to show the childwindow and what message it should display.
首先,您不应该将您的childwindow类带入models文件夹,因为它会破坏MVVM模式。而是将它留在您的views文件夹中。您应该做的是从模型的视图中显示子窗口。要实现这一点,您需要一种方法来告诉您的视图何时显示子窗口以及它应显示的消息。
First, in your model create a property ErrorMessage:
首先,在您的模型中创建一个属性ErrorMessage:
public class MyModel : INotifyPropertyChanged
{ ...
{...
private string _errorMessage;
public string ErrorMessage
{
private set
{
_errorMessage = value;
OnPropertyChanged("ErrorMessage");
}
get { return _errorMessage;; }
}
... }
...}
Note: I assume here that your model class implements INotifyPropertyChanged interface but it could be a different implementation.
注意:我假设您的模型类实现了INotifyPropertyChanged接口,但它可能是一个不同的实现。
Then in your view's code behind add a dependency property and bind it to your model's ErrorMessage. The dependency property's change callback is used to display the childwindow. This could look like the following:
然后在您的视图后面的代码中添加一个依赖项属性并将其绑定到模型的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);
}
...
}
... }
...}
Then every time you change the value of ErrorMessage in your model it should show the childwindow.
然后,每次在模型中更改ErrorMessage的值时,都应显示子窗口。
#1
1
First thing is that you should not bring your childwindow class in the models folder because it breaks the MVVM pattern. Instead leave it in your views folder. What you should do is to show the childwindow from your model's view. To achieve that you need a way to tell your view when to show the childwindow and what message it should display.
首先,您不应该将您的childwindow类带入models文件夹,因为它会破坏MVVM模式。而是将它留在您的views文件夹中。您应该做的是从模型的视图中显示子窗口。要实现这一点,您需要一种方法来告诉您的视图何时显示子窗口以及它应显示的消息。
First, in your model create a property ErrorMessage:
首先,在您的模型中创建一个属性ErrorMessage:
public class MyModel : INotifyPropertyChanged
{ ...
{...
private string _errorMessage;
public string ErrorMessage
{
private set
{
_errorMessage = value;
OnPropertyChanged("ErrorMessage");
}
get { return _errorMessage;; }
}
... }
...}
Note: I assume here that your model class implements INotifyPropertyChanged interface but it could be a different implementation.
注意:我假设您的模型类实现了INotifyPropertyChanged接口,但它可能是一个不同的实现。
Then in your view's code behind add a dependency property and bind it to your model's ErrorMessage. The dependency property's change callback is used to display the childwindow. This could look like the following:
然后在您的视图后面的代码中添加一个依赖项属性并将其绑定到模型的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);
}
...
}
... }
...}
Then every time you change the value of ErrorMessage in your model it should show the childwindow.
然后,每次在模型中更改ErrorMessage的值时,都应显示子窗口。