Архив

Сообщения с тегами 'TypeConverter'

Стоимость имущества Редакторы для управления Silverlight

3 апреля 2009 Без комментариев

Введение

Это является частью серии по дизайну времени осуществления изменений в Silverlight Инструментарий марта 2009 выпуска . Этот пост обсуждает, как повысить собственности редактирования опыт для управления с помощью Silverlight собственности редактор значение и тип преобразователя. Я начну с описания общей архитектуры редактирования собственности в WPF / Silverlight рамках расширения конструктор, а затем использовать примеры Silverlight Инструментарий марта 2009 выпуска , чтобы продемонстрировать, как это делается, и уникальные вопросы / трюки в Silverlight время разработки дизайна.

Редактирование недвижимости Архитектура

Визуально редактирования свойств объекта является важной составной частью наших дизайнеров. Дизайнеры, как правило, не знают, как оказывать свойства пользовательского типа (структура, класс или интерфейс), а тем более обеспечить удобный интерфейс редактирования. Контроль разработчики как правило, необходимо обеспечить TypeConverter , PropertyValueEditor , или оба, чтобы обеспечить оказание / редактирования интерфейса и XAML сериализации свойств пользовательских типов.

Рамках расширения дизайнер определяет три вида собственности редактор значение: встроенный редактор, расширенные редактор и редактор диалогового каждый осуществляться класс:

PropertyValueEditor class diagram

Редактирование интерфейса этих редакторов определяются DataTemplate . Имущества редакцией подвергается редакторе DataContext в PropertyValue типа. Редактор пользовательского интерфейса обычно связывают основные имущества редактировать с помощью одного из трех свойств PropertyValue : Соотношение цена , StringValue или Коллекция .

PropertyValueEditor

PropertyValueEditor имеет встроенный редактор одного определяется InlineEditorTemplate собственности. Inline редактора появляется в окне свойств. Ниже приведен простой пример InlineEditorTemplate который использует TextBox для отображения и редактирования собственности:

  x:Key ="TextBoxEditor" > <DataTemplate х: Key = "TextBoxEditor">
     Text ="{Binding Path=Value}" /> <TextBox Text = "(Переплетные Path = Value)" />
 > </ DataTemplate> 

ExtendedPropertyValueEditor

ExtendedPropertyValueEditor имеет две редакции: встроенный редактор унаследовал от PropertyValueEditor , а также дополнительные расширенный редактор определяется ExtendedEditorTemplate собственности. Расширенный редактор, как правило, выскочил на встроенный редактор с помощью PropertyValueEditorCommands . ShowExtendedPinnedEditor или PropertyValueEditorCommands . ShowExtendedPopupEditor команды. Ниже приведен простой пример: встроенный редактор кнопку, когда нажата, то всплывает расширенного редактора, который использует Slider, чтобы отображать и редактировать основные свойства.
  x:Key ="inlineEditor" > <DataTemplate х: Key = "inlineEditor">
     Content ="..." Command ="{x:Static PropertyEditing:PropertyValueEditorCommands.ShowDialogEditor}" /> <Командной кнопке ="..." Content = "(х: статических PropertyEditing: PropertyValueEditorCommands.ShowDialogEditor)" />
 > </ DataTemplate>
 x:Key ="extendedEditor" xmlns:PropertyEditing ="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design.Interaction" > <DataTemplate х: Key = "extendedEditor" xmlns: PropertyEditing = "CLR-пространство имен: Microsoft.Windows.Design.PropertyEditing; собраний = Microsoft.Windows.Design.Interaction">
     x:Name ="slider" Value ="{Binding Path=Value}" /> <Slider X: Name = "слайдер" Value = "(Переплетные Path = Value)" />
 > </ DataTemplate> 

DialogPropertyValueEditor

DialogPropertyValueEditor имеет два редакторах: встроенный редактор унаследовал от PropertyValueEditor , а также дополнительные редактор диалогового определяется DialogEditorTemplate собственности. Редактора диалога, как правило, выскочил на встроенный редактор с помощью PropertyValueEditorCommands . ShowDialogEditor команды. Ниже приведен простой пример:

  x:Key ="inlineEditor" > <DataTemplate х: Key = "inlineEditor">
     Content ="..." Command ="{x:Static PropertyEditing:PropertyValueEditorCommands.ShowDialogEditor}" /> <Командной кнопке ="..." Content = "(х: статических PropertyEditing: PropertyValueEditorCommands.ShowDialogEditor)" />
 > </ DataTemplate>
 x:Key ="dialogEditor" xmlns:PropertyEditing ="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design" > <DataTemplate х: Key = "dialogEditor" xmlns: PropertyEditing = "CLR-пространство имен: Microsoft.Windows.Design.PropertyEditing; собраний = Microsoft.Windows.Design">
     > <Grid>
         > <Grid.ColumnDefinitions>
             Width ="Auto" /> <ColumnDefinition Ширина = "Auto" />
             Width ="*" /> <ColumnDefinition Ширина = "*" />
         > </ Grid.ColumnDefinitions>
         > <Grid.RowDefinitions>
             Height ="*" /> <RowDefinition Высота = "*" />
             Height ="*" /> <RowDefinition Высота = "*" />
         > </ Grid.RowDefinitions>
         Text ="User Name:" VerticalAlignment ="Center" HorizontalAlignment ="Right" Margin ="0,0,4,4" /> <TextBlock Text = "Имя пользователя:" VerticalAlignment = "Центр" HorizontalAlignment = "правой" Margin = "0,0,4,4" />
         Text ="{Binding Path=Value}" VerticalAlignment ="Center" HorizontalAlignment ="Stretch" Margin ="0,0,4,4" Grid . Column ="1" /> <TextBox Text = "(Переплетные Path = Value)" VerticalAlignment = "Центр" HorizontalAlignment = "Растянуть" Margin = "0,0,4,4" Grid. Колонка = "1" />
     > </> Grid
 > </ DataTemplate> 

Реализация пользовательского редактора собственности

Для реализации пользовательского редактор свойств для управления Silverlight:

  • реализации пользовательского класса редактор собственности
  • Ассоциированные пользовательского редактора собственности с собственностью управления Silverlight с помощью вызова AddCustomAttributes, что-то вроде
      attributeTableBuilder.AddCustomAttributes (
         ЪуреоЕ (MyControl),
         "MyProperty",
         (MyValueEditor))); новые PropertyValueEditor.CreateEditorAttribute (ЪуреоЕ (MyValueEditor))); 

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

  • Редактор стоимости имущества должен быть разработан так, что встроенный редактор и редактор расширенной части может быть использован самостоятельно.
  • Редактор стоимости имущества не должен хранить состояние. Редакторы Стоимость недвижимости являются лицами без гражданства, могут сохраняться в кэше принимающей реализации, и может быть повторно использован в нескольких значениях собственности.
  • Редактор стоимости имущества, не должны считать, что только одно значение редактор часть (просмотреть / встраиваемая / расширенная) контроль активен в данный момент времени. Например, диалоговое окно может иметь вид части, встроенные части, и расширенный пользовательский интерфейс активной части в то же время.
  • Контроль осуществляется как часть редактора стоимость имущества не должен хранить состояние. Контроль осуществляется как часть значения редактор не следует считать, что это будет только быть привязаны к стоимости имущества 1. Управление может быть переработан, чтобы изменить различные значения свойств. Любая информация, которая кэше следует промыть, если модель данных обновляется.
  • Контроль осуществляется как часть редактора стоимость имущества не должны делать никаких предположений о принимающих или его контроля родителей. Только коммуникационных механизмов, которые должны быть применено PropertyValue модели данных, путем DataContext , а также стандартный набор команд.

    И номер WPF и Silverlight Ассамблей

    Проектирование сборка .NET / WPF собраний загружен Visual Studio или Blend, но обычно оно должно ссылка Silverlight собраний (по крайней мере собраний управления Silverlight обеспечивает проектирование возможности для). Это может создать ссылку неоднозначности для разработки проекта сборки: иногда ему приходится ссылаться на тот же полное типа как в WPF и Silverlight, говорят System.Windows.FrameworkElement как PresentationFramework.dll МОФ и System.Windows.dll в Silverlight. Чтобы не смущать Visual Studio, вы можете использовать внешний псевдоним , чтобы отличать WPF и Silverlight ссылки.

    Например, см. скриншот ниже Controls.DataVisualization.Toolkit.Design проекта в Silverlight 3 Инструментарий в марте 2009 выпуска :

    image

    • Проект справочниках как PresentationFramework и System.Windows, но System.Windows находится под Silverlight псевдоним, а по умолчанию глобальный псевдоним. Ссылка System.Windows под вымышленным именем, Silverlight является упорно. Csproj файл, как показано ниже:
        Include ="System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, processorArchitecture=MSIL" > <Номер Включить = "System.Windows, Version = 2.0.5.0, Culture = нейтральной, PublicKeyToken = 7cec85d7bea7798e, processorArchitecture = MSIL">
         > False </ SpecificVersion > <SpecificVersion> False </> SpecificVersion
         > ..\Binaries\System.Windows.dll </ HintPath > <HintPath> .. \ Binaries \ System.Windows.dll </ HintPath>
         > False </ Private > <Частные> False </ Частным лицам>
         > Silverlight </ Aliases > <Синонимы> <Silverlight / Псевдонимы>
       > </> Справочники 

    • в исходном коде, мы добавили
        внешних псевдоним Silverlight;
       SSW использованием Silverlight =:: System.Windows; 

      и FrameworkElement ссылки в Silverlight с помощью SSW:: FrameworkElement.

    TextBoxEditor

    Существует встроенный редактор TextBoxEditor в проекте Controls.DataVisualization.Toolkit.Design для отображения и редактирования Название свойство объекта типа [района | Бар | пузыря | Колонка | линия | Pie | Scatter] Серии и диаграммы контроля, как показано ниже:

    TextBoxEditor

    Текст заполнить поле "Заголовок" в окне "Свойства" справа появляется автоматически в XAML и дизайн просмотра в середине.

    Осуществление TextBoxEditor после шагам, до:

    TextBoxEditor.cs

    • TextBoxEditor это подкласс PropertyValueEditor. Он устанавливает InlineEditorTemplate в его конструктор по умолчанию. Здесь я использую код XAML, а не построить DataTemplate , потому что иначе я не могу получить XAML, чтобы строить, и все в XAML можно переписать в C # в любом случае.
    • Это связано с Chart.Title в ChartMetadata.cs (см. Дизайн Время выполнения функций в Silverlight Инструментарий для получения дополнительной информации на * Metadata.cs файлы)

    TextBoxEditor.cs:

      / / (C) Copyright Корпорация Microsoft.
     / / Этот источник может быть Microsoft Public License (Ms-PL).
     / / См. http://go.microsoft.com/fwlink/?LinkID=131993 для деталей.
     / / Все остальные права защищены.
    
     использования системы;
     использованием Microsoft.Windows.Design.PropertyEditing;
     использованием System.Windows;
     использованием System.Windows.Data;
    
     имен System.Windows.Controls.DataVisualization.Design
     (
         / / / <summary>
         / / / Простой TextBox встроенный редактор.
         / / / </> Резюме
         общественного частичный класс TextBoxEditor: PropertyValueEditor
         (
             / / / <summary>
             / / / Заповедник конструктор прототипа из PropertyValueEditor.
             / / / </> Резюме
             / / / <param Name="inlineEditorTemplate"> Inline редактор шаблона. </> Параметр
             общественного TextBoxEditor (DataTemplate inlineEditorTemplate)
                 : Базовый (inlineEditorTemplate)
             ()
    
             / / / <summary>
             / / / Конструктор по умолчанию создает по умолчанию встроенный редактор TextBox шаблона.
             / / / </> Резюме
             общественного TextBoxEditor ()
             (
                 (TextBox)); FrameworkElementFactory TextBox = новый FrameworkElementFactory (ЪуреоЕ (TextBox));
                 Переплетные обязательного новых обязательных = ();
                 ); binding.Path = новый PropertyPath ("Значение");
                 binding.Mode = BindingMode.TwoWay;
                 textBox.SetBinding (TextBox.TextProperty, переплет);
    
                 DataTemplate DT = новый DataTemplate ();
                 dt.VisualTree = TextBox;
    
                 InlineEditorTemplate = DT;
             )
         )
     ) 

    CultureInfoEditor

    Мой коллега RJ пишет встроенный редактор CultureInfoEditor собственности TimePicker.Culture, потому что опыт редактирования по умолчанию для CultureInfo в Blend приводит к недействительными XAML. Ниже скриншот показывает CultureInfoEditor использует ComboBox, чтобы показать все CultureInfo и порождает право XAML.

    CultureInfoEditor

    CultureInfoEditor представляет собой более сложный пример, чем TextBoxEditor, действительно показывает, как основного имущества связан с редактором по собственности DataContext.

    CultureInfoEditor.cs:

     System.Reflection; using Microsoft.Windows.Design.PropertyEditing; using System.Globalization; using System.ComponentModel; namespace System.Windows.Controls.Input.Design { /// <summary> /// Editor for CultureInfo. /// </summary> /// <remarks>Currently does not support binding from xaml to the editor.</remarks> public class CultureInfoEditor : PropertyValueEditor { /// <summary> /// The ComboBox being used to edit the value. /// </summary> private ComboBox _owner; /// <summary> /// Preserve the constructor prototype from PropertyValueEditor. /// </summary> /// <param name="inlineEditorTemplate">Inline editor template.</param> public CultureInfoEditor(DataTemplate inlineEditorTemplate) : base (inlineEditorTemplate) { } /// <summary> /// Default constructor builds a ComboBox inline editor template. /// </summary> public CultureInfoEditor() { // not using databinding here because Silverlight does not support // the WPF CultureConverter that is used by Blend. FrameworkElementFactory comboBox = new FrameworkElementFactory( typeof (ComboBox)); comboBox.AddHandler( ComboBox.LoadedEvent, new RoutedEventHandler( (sender, e) => { _owner = (ComboBox) sender; _owner.SelectionChanged += EditorSelectionChanged; INotifyPropertyChanged data = _owner.DataContext as INotifyPropertyChanged; if (data != null ) { data.PropertyChanged += DatacontextPropertyChanged; } _owner.DataContextChanged += CultureDatacontextChanged; })); comboBox.SetValue(ComboBox.IsEditableProperty, false ); comboBox.SetValue(ComboBox.DisplayMemberPathProperty, "DisplayName" ); comboBox.SetValue(ComboBox.ItemsSourceProperty, CultureInfo.GetCultures(CultureTypes.SpecificCultures)); DataTemplate dt = new DataTemplate(); dt.VisualTree = comboBox; InlineEditorTemplate = dt; } /// <summary> /// Handles the SelectionChanged event of the owner control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.Windows.Controls.SelectionChangedEventArgs"/> /// instance containing the event data.</param> private void EditorSelectionChanged( object sender, SelectionChangedEventArgs e) { // serialize with name. object DataContext = _owner.DataContext; DataContext .GetType() .GetProperty( "Value" , BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty) .SetValue(DataContext, ((CultureInfo)_owner.SelectedItem).Name, new object [] { }); } /// <summary> /// Handles the PropertyChanged event of the context object. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param> private void DatacontextPropertyChanged( object sender, PropertyChangedEventArgs e) { // deserialize from name. if (e.PropertyName == "Value" ) { object value = sender .GetType() .GetProperty( "Value" , BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty) .GetValue(sender, new object [] { }); if ( value != null ) { if ( value is string ) { CultureInfo setCulture = new CultureInfo( value .ToString()); _owner.SelectedItem = setCulture; } } } } /// <summary> /// Called when the context is changed. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param> private void CultureDatacontextChanged( object sender, DependencyPropertyChangedEventArgs e) { INotifyPropertyChanged old = e.OldValue as INotifyPropertyChanged; if (old != null ) { old.PropertyChanged -= DatacontextPropertyChanged; } INotifyPropertyChanged newDataContext = e.NewValue as INotifyPropertyChanged; if (newDataContext != null ) { newDataContext.PropertyChanged += DatacontextPropertyChanged; } } } } / / (C) Copyright Microsoft Corporation. / / Этот источник может быть Microsoft Public License (Ms-PL). / / См. http://go.microsoft.com/fwlink/?LinkID=131993 для деталей. / / Все другие права защищены. System.Reflection использования, использования Microsoft.Windows.Design.PropertyEditing, использования System.Globalization, использования System.ComponentModel; имен System.Windows.Controls.Input.Design (/ / / <summary> / / / Редактор CultureInfo. / / / </ резюме> / / / <remarks> В настоящее время не поддерживает обязательный из XAML в окно редактора. </ замечания> общественного класса CultureInfoEditor: PropertyValueEditor (/ / / <summary> / / / ComboBox время используется для изменения значения. / / / </ резюме> частного _owner ComboBox / / / <summary> / / / Заповедник конструктор прототипа из PropertyValueEditor. / / / </ резюме> / / / <имя параметра = "inlineEditorTemplate" > Inline редактор шаблона. </ параметр> общественного CultureInfoEditor (DataTemplate inlineEditorTemplate): базовый (inlineEditorTemplate) () / / / <summary> / / / Конструктор по умолчанию создает встроенный редактор ComboBox шаблона. / / / </ резюме> общественного CultureInfoEditor ( ) (/ / не используется привязка данных здесь потому, что Silverlight не поддерживает / / WPF CultureConverter, который используется Blend. FrameworkElementFactory ComboBox = новый FrameworkElementFactory (ЪуреоЕ (ComboBox)); comboBox.AddHandler (ComboBox.LoadedEvent новые RoutedEventHandler ((отправитель, е) => (_owner = (ComboBox) отправителя; _owner.SelectionChanged + = EditorSelectionChanged; INotifyPropertyChanged данных = _owner.DataContext как INotifyPropertyChanged, если (данные! = NULL) (data.PropertyChanged + = DatacontextPropertyChanged;) _owner.DataContextChanged + = CultureDatacontextChanged ;))); comboBox.SetValue (ComboBox.IsEditableProperty, ложные); comboBox.SetValue (ComboBox.DisplayMemberPathProperty, "DisplayName"); comboBox.SetValue (ComboBox.ItemsSourceProperty, CultureInfo.GetCultures (CultureTypes.SpecificCultures)); DataTemplate DT = новые DataTemplate (); dt.VisualTree = ComboBox; InlineEditorTemplate = DT;) / / / <summary> / / / Ручки SelectionChanged случае владелец контроля. / / / </ резюме> / / / <имя параметра = "отправитель "> источника события. </ параметр> / / / <param name="E"> <see cref="System.Windows.Controls.SelectionChangedEventArgs"/> / / / например содержащие данные о событии. </ параметр> частного недействительными EditorSelectionChanged (объект отправителя, SelectionChangedEventArgs е) (/ / сериализации с именем. объект DataContext = _owner.DataContext; DataContext. Туре (). GetProperty ("Значение", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty) . SetValue (DataContext, ((CultureInfo) _owner.SelectedItem). Имя нового объекта [] ());) / / / <summary> / / / Ручки PropertyChanged случае контексте объекта. / / / </> резюме / / / <param name="sender"> источник события. </ параметр> / / / <param name="E"> <see например cref="System.ComponentModel.PropertyChangedEventArgs"/> содержащие события данных. </ параметр> частного недействительными DatacontextPropertyChanged (объект отправителя, PropertyChangedEventArgs е) (/ / десериализации из названия. если (e.PropertyName == "Значение") (стоимости объекта = отправителя. Туре (). GetProperty ("Значение", BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty). GetValue (отправитель, новый объект [] ()), если (значение! = NULL) (если (значение строки) (CultureInfo setCulture = новый CultureInfo (стоимости. ToString ( )); = setCulture _owner.SelectedItem;)))) / / / <summary> / / / Вызывается, когда контекст изменился. / / / </ резюме> / / / <param name="sender"> отправителя. </> параметра / / / <param name="E"> <see например cref="System.Windows.DependencyPropertyChangedEventArgs"/> содержащий данные о событии. </ параметр> частного недействительными CultureDatacontextChanged (объект отправителя, DependencyPropertyChangedEventArgs е) ( INotifyPropertyChanged старых e.OldValue = как INotifyPropertyChanged, если (старых! = NULL) (old.PropertyChanged -= DatacontextPropertyChanged;) INotifyPropertyChanged newDataContext = e.NewValue как INotifyPropertyChanged, если (newDataContext! = NULL) (newDataContext.PropertyChanged + = DatacontextPropertyChanged;) ))) 

    ExpandableObjectConverter

    Как уже говорилось в начале, кроме пользовательских редакторов стоимость имущества, то вы можете использовать соответствующий конвертер типа для обеспечения хорошего опыта редактирования и XAML сериализации. Одним из примеров является ColumnSeries.DependentRangeAxis: это типа IRangeAxis, Blend не знаю, как изменить его, так он показывает DependentRangeAxis только для чтения в свойствах панели. Связав ExpandableObjectConverter к ColumnSeries.DependentRangeAxis:

      b.AddCustomAttributes (
         Extensions.GetMemberName <ColumnSeries> (х => x.DependentRangeAxis),
         (ExpandableObjectConverter))); новые TypeConverterAttribute (ЪуреоЕ (ExpandableObjectConverter)));
     b.AddCustomAttributes (
         Extensions.GetMemberName <ColumnSeries> (х => x.IndependentAxis),
         (ExpandableObjectConverter))); новые TypeConverterAttribute (ЪуреоЕ (ExpandableObjectConverter))); 

    Blend отображает кнопку Создать рядом с этим имуществом в панель свойств, а при нажатии на него всплывает диалоговое Выберите объект, фильтруется с типом недвижимости IRangeAxis:

    ExpandableObjectConverter

    Заключение

    Blend и Silverlight вместе позволяют разработчикам создавать удивительные интерфейса против реальных контроля напрямую, так что очень важно, что контроль разработчиков принять дизайнер опытом в рамках общей структуры управления и реализации. Наличие пользовательских редактор свойств, который обеспечивает хороший редактирования интерфейса и генерирует правильный XAML является важной частью опыта дизайнера. Надеюсь, этот пост поможет вам понять, как создавать собственные редакторы собственности. Спасибо!

    Делите и наслаждайтесь:

    • Print
    • email
    • RSS
    • Twitter
    • TwitThis
    • del.icio.us
    • LinkedIn
    • Technorati
    • Facebook
    • Google Bookmarks
    • Live
    • MySpace
    • QQ书签