【问题标题】:Binding data items on second window在第二个窗口上绑定数据项
【发布时间】:2011-09-10 10:26:49
【问题描述】:

最后,我决定加入 WPF 潮流,并决定遵循 MVVM 模式来创建我的应用程序。我也在使用 Caliburn.Micro。

我发现了许多将数据绑定到 Windows 的示例,但所有示例都只包含一个 MainWindow。打开第二个和第三个窗口时,我不知道如何引用和进行绑定。为了说明我的问题,我创建了一个简单的应用程序。此应用程序有两个窗口,主窗口名为 ShellView,第二个窗口名为 Window1View。在这个应用程序中,我只需要将 myStr1 的内容显示到 Window1View 上的 TextBox 中。

代码如下:

Views.ShellView.xaml

<Window x:Class="Test.Views.ShellView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <TextBlock x:Name="Title" />
        <Button Content="Window 1" Height="31" HorizontalAlignment="Left" Margin="24,268,0,0" Name="btnWin1" VerticalAlignment="Top" Width="87" Click="btnWin1_click" />
    </Grid>
</Window>

Views.ShellView.xaml.cs

namespace Test.Views
{
    using System.Windows;

    public partial class ShellView : Window
    {
        public ShellView()
        {
            InitializeComponent();
        }

        private void btnWin1_click(object sender, RoutedEventArgs e)
        {
            Window1View win1 = new Window1View();
            win1.Show();
        }
    }
}

ViewModels.ShellViewModel.cs

namespace Test.ViewModels
{
    using Caliburn.Micro;

    public class ShellViewModel : PropertyChangedBase
    {
        public static string txt1 = "String 1";
        public static string txt2 = "String 2";

        private string title;
        public string Title
        {
            get { return title; }
            set
            {
                if (title != value)
                {
                    title = value;
                    RaisePropertyChangedEventImmediately("Title");
                }
            }
        }

        public ShellViewModel()
        {
            Title = "Hello Caliburn.Micro";
        }
    }
}

Views.Window1View.xaml

<Window x:Class="Test.Views.Window1View"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:c="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"
        Title="Window 1" Height="300" Width="300">
    <Grid>
        <Label Content="TextBox 1" Height="26" HorizontalAlignment="Left" Margin="12,40,0,0" Name="label1" VerticalAlignment="Top" Width="75" />
        <TextBox Height="29" HorizontalAlignment="Left" Margin="106,39,0,0" Name="txtBox1" VerticalAlignment="Top" Width="145" Text="{Binding myStr1}" />
    </Grid>
</Window>

View.Window1View.xaml.cs

using System.Windows;

namespace Test.Views
{
    /// <summary>
    /// Interaction logic for Window1View.xaml
    /// </summary>
    public partial class Window1View : Window
    {
        public Window1View()
        {
            InitializeComponent();
        }
    }
}

ViewModels.Window1ViewModel.cs

namespace Test.ViewModels
{
    class Window1ViewModel
    {
        public Window1ViewModel()
        {
            myStr1 = ShellViewModel.txt1;
        }

        public string myStr1 { get; set; }
    }
}

Bootstrapper.cs

namespace Test
{
    public class Bootstrapper : Caliburn.Micro.Bootstrapper<Test.ViewModels.ShellViewModel>
    {
    }
}

App.xaml

<Application 
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Class="Test.App">
    <Application.Resources>

    </Application.Resources>
</Application>

App.xaml.cs

namespace Test
{
    using System.Windows;

    public partial class App : Application
    {
        Bootstrapper bootstrapper;

        public App()
        {
            bootstrapper = new Bootstrapper();
        }
    }
}

对此的任何帮助将不胜感激。
谢谢
卡梅罗

【问题讨论】:

  • Wth,男人/女人。如果你想让人们看到整个项目,只需在某处上传一个压缩文件。

标签: c# wpf xaml binding caliburn.micro


【解决方案1】:

这里有几件事:

  1. 您使用了不必要的代码。理想情况下,在使用 MVVM 时,您的目标应该是几乎没有代码落后。不要创建btnWin1_click 处理程序,而是命名按钮并在视图模型上实现一个具有相同名称的方法。 Caliburn.Micro 将根据约定调用视图模型方法。
  2. 使用 x:Name 而不是 Name
  3. 显示Window1ViewModel 时,您没有使用Caliburn.Micro 来调用窗口显示。这意味着您的Window1ViewWindow1ViewModel 之间不存在绑定。如果这是一个单独的窗口,请使用 Caliburn.Micro 中的 WindowManager 类型。实例化您的Window1ViewModel,并使用WindowManager 类来显示它。 Caliburn.Micro 将根据约定定位适当的视图,并将视图绑定到您的视图模型。
  4. 如前所述,不要直接在Window1ViewModel 中引用ShellViewModel(它会耦合视图模型并降低Window1ViewModel 的可重用性),而是使用中介模式。 Caliburn.Micro 带有一个 EventAggregator 类 - 您可以从 ShellViewModel 发布文本更改,并在您的 Window1ViewModel 订阅事件。

【讨论】:

  • 查看 Rob 的 3 系列文章,从这里开始了解屏幕导航的工作原理。 devlicio.us/blogs/rob_eisenberg/archive/2010/10/08/…。还要检查 caliburn 下载中包含的示例。
  • 感谢 devdigital,您的回复已经消除了很多迷雾。我会根据您的建议尝试让我的示例代码正常工作。
【解决方案2】:

在 MVVM 中实现视图模型通信的常用方法是使用Mediator Pattern。大多数 MVVM 框架都包含一个“Messenger”类,它允许您通过发布和订阅事件来解耦您的设计。在 Caliburn Micro 中,EventAggregator 类支持中介。

由于您是 MVVM 新手,我还推荐以下资源:

【讨论】:

  • 反对,我一定会研究你提到的中介者模式。也感谢您提供的资源。
【解决方案3】:

也许因为我不熟悉 Caliburn.Micro,所以我遗漏了一些东西,但我看到这里发生了一些事情。

首先,我看不到您将Window1ViewDataContext 设置为Window1ViewModel 的实例。

其次,您的Window1ViewModel 不是从PropertyChangedBase 派生的,并且您在更改 myStr1 属性时不会调用RaisePropertyChanged

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    相关资源
    最近更新 更多