Какой шаблон дизайна я должен использовать для создания таких диалогов? - PullRequest
0 голосов
/ 16 марта 2011

Я хочу разработать диалог для редактирования объектов, использующих полиморфизм. В настоящее время я использую этот шаблон:

MyObject.cs:

using System;

namespace WpfApplication3
{
    public class MyObject
    {
        public string Title { get; set; }
        public MySettings Settings { get; set; }
    }

    public abstract class MySettings
    {
        public abstract string GetSettingsString();
    }

    public class MyBoolSettings : MySettings
    {
        public bool BoolSetting { get; set; }

        public override string GetSettingsString()
        {
            return "BoolSetting = " + BoolSetting;
        }
    }

    public class MyStringSettings : MySettings
    {
        public string StringSetting { get; set; }

        public override string GetSettingsString()
        {
            return "StringSetting = " + StringSetting;
        }
    }
}

MainWindow.xaml:

<Window x:Class="WpfApplication3.EditMyObjectDialog"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="EditMyObjectDialog" Height="350" Width="350">
    <StackPanel Margin="20">
        <TextBlock Text="Title" />
        <TextBox Name="txtTitle" />
        <RadioButton Name="rdBoolSettings" Content="BoolSettings" IsChecked="True" Margin="0, 20, 0, 0" />
        <CheckBox Name="chBool" Content="True" Margin="20, 0, 0, 20" />
        <RadioButton Name="rdStringSettings" Content="StringSettings" />
        <TextBox Name="txtString" Margin="20, 0, 0, 20"/>
        <Button Content="OK" Click="OK_click" />
        <Button Content="Cancel" Click="Cancel_click" Margin="0, 10" />
    </StackPanel>
</Window>

MainWindow.xaml.cs:

using System.Windows;

namespace WpfApplication3
{
    public partial class EditMyObjectDialog : Window
    {
        public MyObject Result { get; set; }

        public EditMyObjectDialog(MyObject objectToEdit)
        {
            InitializeComponent();
            txtTitle.Text = objectToEdit.Title;
            if (objectToEdit.Settings is MyBoolSettings)
            {
                rdBoolSettings.IsChecked = true;
                chBool.IsChecked = (objectToEdit.Settings as MyBoolSettings).BoolSetting;
            }
            if (objectToEdit.Settings is MyStringSettings)
            {
                rdBoolSettings.IsChecked = true;
                txtString.Text = (objectToEdit.Settings as MyStringSettings).StringSetting;
            }
        }

        private void OK_click(object sender, RoutedEventArgs e)
        {
            Result = new MyObject() { Title = txtTitle.Text };
            if (rdBoolSettings.IsChecked == true) 
                Result.Settings = new MyBoolSettings() { BoolSetting = chBool.IsChecked == true };
            if (rdStringSettings.IsChecked == true)
                Result.Settings = new MyStringSettings() { StringSetting = txtString.Text };
            DialogResult = true;
        }

        private void Cancel_click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
        }
    }
}

ExternalCode:

var f = new EditMyObjectDialog(myObject);
if (f.ShowDialog() == true)
    myObject = f.Result;

Я полагаю, что существует гораздо лучший шаблон проектирования, в котором используется привязка данных и т. Д. Поэтому в основном у меня есть два вопроса.

  1. Как сделать привязку данных не к изменять объект, пока пользователь не нажмет «ОК»?
  2. Как правильно обрабатывать «Настройки» имущество? Что делать, когда пользователь переключает тип настройки?

Ответы [ 3 ]

1 голос
/ 16 марта 2011

Я считаю, что вы ищете комбинацию DataBinding и DataTemplating. DataTemplating позволит вам определять разные визуальные элементы для разных бизнес-объектов (в данном случае MyBooleanSettings и MyStringSettings. DataBinding позволит визуальным элементам обновлять и обновлять мои данные в бизнес-объектах.

Пример (xaml):

<Window DataContext={Binding RelativeSource={RelativeSource Self}}">
    <Window.Resources>
        <DataTemplate DataType={x:Type local:MyObject}">
            <TextBlock Text={Binding Title}" />
            <ContentPresenter Content="{Binding Settings}" />
        </DataTemplate>
        <DataTemplate DataType={x:Type local:MyObject}">
            <TextBox Text={Binding 
        </DataTemplate>
        <DataTemplate DataType={x:Type local:MyBoolSettings}>
            <CheckBox IsChecked="{Binding BoolSetting}" />
        </DataTemplate>
        <DataTemplate DataType={x:Type local:MyStringSettings}>
            <TextBox Text="{Binding StringSetting}" />
        </DataTemplate>
    </Window.Resources>
    <ContentPresenter Content="{Binding ObjectToEdit}" />
</Window>

Затем в коде определения:

public MyObject ObjectToEdit { get; set; }

Наконец обновите ваши объекты:

public class MySettings : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(sting s)
    {
        if(PropertyChanged != null)
        {
            PropertyChanged(s);
        }
    }
}

public class BoolSettings : MySettings
{
    bool _value;

    bool BoolSetting
    {
        get { return _value; }
        set
        {
            if(_value != value)
            {
                _value = value;
                OnPropertyChanged("BoolSetting");
            }
         }
    }
}

Если, однако, вам действительно необходимо контролировать время синхронизации вида и объекта, следует использовать свойство UpdateSourceTrigger для соответствующих привязок.

Если вам нужно дополнительное чтение, я рекомендую: http://msdn.microsoft.com/en-us/library/ms752347.aspx

0 голосов
/ 16 марта 2011
  1. Как сделать привязку данных, чтобы не изменять объект, пока пользователь не нажмет 'OK'?

Создать копию экземпляра MyObject.В методе Result получить метод return return, если пользователь нажал «Cancel» (вернуть неизмененную копию) или «OK», вернуть измененный экземпляр MyObject.

  1. Как правильно обрабатывать свойство «Настройки»?Что делать, когда пользователь переключает тип настройки?

В чем проблема?

0 голосов
/ 16 марта 2011

Привязка данных проста.Вы можете создать экземпляр MyObject и назначить его свойству DataContext формы.

this.DataContext=MyObject;

И определить привязку для отдельных элементов.

 <TextBox Name="txtTitle" Text="{Binding Path=Title,Mode=TwoWay }" />

Настройка режима, как два способа повлияетобъект, как вы вносите изменения в пользовательском интерфейсе.Один из способов покажет значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...