开发者

Binding data items on second window

开发者 https://www.devze.com 2023-03-10 22:25 出处:网络
Finally I decided to jump on the WPF bandwagon and decided to follow the MVVM Pattern to create my applications. I am also using Caliburn.Micro.

Finally I decided to jump on the WPF bandwagon and decided to follow the MVVM Pattern to create my applications. I am also using Caliburn.Micro.

I found many examples of Binding data to Windows but all the examples contained just one MainWindow. I couldn't figure out how to reference and make the binding when opening a second and third window. To illustrate my problem I created a simple application. This application has two windows, the main one named ShellView and the second one named Window1View. All I need in this application is to display the content of myStr1 into the TextBox on Window1View.

Here is the code:

Views.ShellView.xaml

<Window x:Class="Test.Views.ShellView"
        xmlns="ht开发者_StackOverflow社区tp://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();
        }
    }
}

Any help with this would be greatly appreciated.

Thanks

Carmelo


Maybe I'm missing something because I'm not familiar with Caliburn.Micro, but I see a couple of things going on here.

First, I don't see anywhere that you're setting the DataContext of the Window1View to be an instance of Window1ViewModel.

Second, your Window1ViewModel doesn't derive from PropertyChangedBase and you don't call RaisePropertyChanged when you change the myStr1 property.


A common way to implement view model communication in MVVM is to use the Mediator Pattern. Most MVVM frameworks include a 'Messenger' class that allows you to decouple your design by publishing and subscribing to events. In Caliburn Micro, mediation is supported by the EventAggregator class.

Since you are new to MVVM, I would also recommend the following resources:

  • Implementing the MVVM Pattern
  • Advanced MVVM Scenarios
  • User Interaction Patterns


A few things here:

  1. You are using code behind unnecessarily. Ideally you should aim for virtually no code behind when using MVVM. Instead of creating a btnWin1_click handler, name the button and implement a method on your view model with the same name. Caliburn.Micro will invoke the view model method based on convention.
  2. Use x:Name rather than Name
  3. When displaying the Window1ViewModel, you are not using Caliburn.Micro to invoke the window display. This means that no binding exists between your Window1View and Window1ViewModel. If this is a separate window, use the WindowManager type from Caliburn.Micro. Instantiate your Window1ViewModel, and use the WindowManager class to display it. Caliburn.Micro will locate the appropriate view based on conventions, and bind the view to your view model.
  4. As mentioned, rather than reference the ShellViewModel directly in the Window1ViewModel (which couples the view models and makes Window1ViewModel less reuseable), use the mediator pattern. Caliburn.Micro comes with an EventAggregator class - you can publish the change in text from the ShellViewModel, and subscribe to the event in your Window1ViewModel.
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号