Связывание элементов данных во втором окне - PullRequest
1 голос
/ 08 июня 2011

Наконец, я решил перейти на WPF и решил использовать шаблон MVVM для создания своих приложений. Я также использую Caliburn.Micro.

Я нашел много примеров привязки данных к Windows, но все примеры содержали только одно MainWindow. Я не мог понять, как ссылаться и делать привязку при открытии второго и третьего окна. Чтобы проиллюстрировать мою проблему, я создал простое приложение. Это приложение имеет два окна: основное с именем ShellView и второе с именем Window1View. Все, что мне нужно в этом приложении - это отобразить содержимое myStr1 в TextBox в Window1View.

Вот код:

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();
        }
    }
}

Любая помощь с этим будет принята с благодарностью.
Благодаря
Кармело

Ответы [ 3 ]

0 голосов
/ 08 июня 2011

Обычным способом реализации связи модели представления в MVVM является использование Mediator Pattern . Большинство сред MVVM включают в себя класс «Messenger», который позволяет отделить ваш дизайн путем публикации и подписки на события. В Caliburn Micro медиация поддерживается классом EventAggregator .

Поскольку вы новичок в MVVM, я бы также порекомендовал следующие ресурсы:

0 голосов
/ 08 июня 2011

Несколько вещей здесь:

  1. Вы используете ненужный код.В идеале вы должны стремиться к практически отсутствию кода при использовании MVVM.Вместо того, чтобы создавать обработчик btnWin1_click, назовите кнопку и реализуйте метод в вашей модели представления с тем же именем.Caliburn.Micro будет вызывать метод модели представления на основе соглашения.
  2. Использовать x: Name вместо Name
  3. При отображении Window1ViewModel вы не используете Caliburn.Micro для вызова окнадисплей.Это означает, что между вашими Window1View и Window1ViewModel не существует привязки.Если это отдельное окно, используйте тип WindowManager из Caliburn.Micro.Создайте экземпляр Window1ViewModel и используйте класс WindowManager для его отображения.Caliburn.Micro найдет соответствующий вид на основе соглашений и свяжет вид с моделью вашего вида.
  4. Как уже упоминалось, вместо того, чтобы ссылаться на ShellViewModel непосредственно в Window1ViewModel (который объединяет модели вида иделает Window1ViewModel менее пригодным для повторного использования), используйте шаблон-посредник.Caliburn.Micro поставляется с классом EventAggregator - вы можете опубликовать изменение текста из ShellViewModel и подписаться на событие в своем Window1ViewModel.
0 голосов
/ 08 июня 2011

Может быть, я что-то упускаю, потому что я не знаком с Caliburn.Micro, но я вижу, что здесь происходит несколько вещей.

Во-первых, я нигде не вижу, чтобы вы устанавливали DataContext из Window1View как экземпляр Window1ViewModel.

Во-вторых, ваш Window1ViewModel не является производным от PropertyChangedBase, и вы не вызываете RaisePropertyChanged при изменении свойства myStr1.

...