正在第二个窗口上绑定数据项
本文关键字:绑定 数据项 窗口 第二个 | 更新日期: 2023-09-27 17:58:31
最后我决定加入WPF的潮流,并决定遵循MVVM模式来创建我的应用程序。我也在使用Caliburn.Micro.
我发现了许多将数据绑定到Windows的示例,但所有示例都只包含一个MainWindow。打开第二个和第三个窗口时,我不知道如何引用和绑定。为了说明我的问题,我创建了一个简单的应用程序。此应用程序有两个窗口,主窗口名为ShellView,第二个窗口名为Window1View。在这个应用程序中,我只需要在Window1View的TextBox中显示myStr1的内容。
这是代码:
视图.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; }
}
}
引导程序.cs
namespace Test
{
public class Bootstrapper : Caliburn.Micro.Bootstrapper<Test.ViewModels.ShellViewModel>
{
}
}
应用程序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>
应用程序.xaml.cs
namespace Test
{
using System.Windows;
public partial class App : Application
{
Bootstrapper bootstrapper;
public App()
{
bootstrapper = new Bootstrapper();
}
}
}
如有任何帮助,我们将不胜感激
谢谢
Carmelo
也许我错过了一些东西,因为我不熟悉Caliburn.Micro,但我看到这里发生了一些事情。
首先,我看不到您正在将Window1View
的DataContext
设置为Window1ViewModel
的实例。
其次,您的Window1ViewModel
不是从PropertyChangedBase
派生的,并且在更改myStr1属性时也不会调用RaisePropertyChanged
。
在MVVM中实现视图模型通信的一种常见方法是使用中介模式。大多数MVVM框架都包含一个"Messenger"类,它允许您通过发布和订阅事件来解耦设计。在Caliburn Micro中,EventAggregator类支持中介。
由于您是MVVM的新手,我还推荐以下资源:
- MVVM模式的实现
- 高级MVVM场景
- 用户交互模式
这里有几件事:
- 您在不必要地使用代码隐藏。理想情况下,在使用MVVM时,您应该以几乎没有代码落后为目标。与其创建
btnWin1_click
处理程序,不如命名按钮并在视图模型上实现一个同名方法。Micro将调用基于约定的视图模型方法 - 使用x:Name而不是Name
- 显示
Window1ViewModel
时,您没有使用Caliburn.Micro调用窗口显示。这意味着您的Window1View
和Window1ViewModel
之间不存在绑定。如果这是一个单独的窗口,请使用Caliburn.Micro.中的WindowManager
类型。实例化您的Window1ViewModel
,并使用WindowManager
类来显示它。Caliburn.Micro将根据约定找到合适的视图,并将视图绑定到您的视图模型 - 如前所述,与其直接在
Window1ViewModel
中引用ShellViewModel
(这会耦合视图模型并降低Window1ViewModel
的可重用性),不如使用中介模式。Caliburn.Micro附带一个EventAggregator类-您可以在ShellViewModel
中以文本形式发布更改,并在Window1ViewModel
中订阅该事件