2016-02-08 2 views
0

Вопрос не в том, как заставить работу работать, она уже делает; это о каком-то странном поведении, которое я испытываю, и мне нужно это понять. У меня есть ResourceDictionary, который содержит некоторые стили, один из них получил TargetType="{x:Type UserControl}" и x:Key="UCStyle"; что один применяется к нескольким UserControl с в проекте. Некоторые из этих UserControl s получили string State свойство в их ViewModel, которое будет использоваться для применения визуальных состояний (через внешний класс и прикрепленное свойство, привязанное к ViewModel в XAML). До этого момента все было идеально, то, я пытался добавить DependencyProperty State к UserControl, и просто привязать его к государственной собственности в ViewModel, моя попытка была:Как связать свойство DependencyProperty UserControl с объектом в его ViewModel в MVVM?

<UserControl.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <!--ResourceDictionary Source="..."/--> 
     </ResourceDictionary.MergedDictionaries> 
     <Style x:Key="MyStyle" TargetType="{x:Type local:MyUserControl}" BasedOn="{StaticResource UCStyle}"> 
      <Setter Property="State" Value="{Binding State, Mode=TwoWay}"/> 
     </Style> 
    </ResourceDictionary> 
</UserControl.Resources> 
<UserControl.Style> 
    <DynamicResourceExtension ResourceKey="MyStyle" /> 
</UserControl.Style> 

Это работало отлично на время выполнения, но в дизайн-время, он всегда подчеркивают эти строки 'MyUserControl' TargetType doesn't match type of element 'UserControl'.

И показывает ошибка говорит:

TargetType «MyUserControl» не соответствует типу элемента 'UserControl.

И не применяется ни UCStyle, ни MyStyle в XAML просмотра в Visual Studio, и даже не привлечь ребенка UserControl s правильно. Я не ожидал, что решение будет работать правильно, но это так!

Теперь мои вопросы:

  • Почему показывают эти ошибки в дизайн-время он работает должным образом?
  • Как избавиться от этих ошибок во время разработки? (Я очистил и снова построил решение, и перезапустил Visual Studio, и ни одна из них не сработала)
  • Какова наилучшая практика работы с визуальными состояниями `UserControl` в такой ситуации в MVVM?
  • Какова наилучшая практика привязки DependencyProperty UserControl к свойству в ViewModel в MVVM?

Я использую Visual Studio 2012.

+0

Немного странно, что вы используете 'TargetType =" {x: Тип local: MyUserControl} ", но используйте' 'Tag. Должен ли тег также быть '' тоже? Поскольку это сообщение об ошибке действительно говорит/жалуется на – Tseng

+0

@Tseng, если бы я это сделал, я бы наследовал '' от '' .. –

ответ

2

Дизайнер МОФА является отвратительным для показа фиктивных ошибок во время разработки. Вы не можете многое сделать, но игнорировать их.

Визуальные состояния являются предметом озабоченности пользовательского интерфейса и поэтому должны содержаться в пользовательском интерфейсе. MVVM не нет нет кодbehind. Используйте свой код для задач пользовательского интерфейса и поместите свою бизнес-логику в свои модели просмотра.

Ваш вопрос предполагает, что вы создаете пользовательские модели просмотра для хранения логики просмотра для пользовательских элементов управления. Серьезно, не делайте этого. Это приведет вас в беду по дороге. Это мешает тому, как привязка данных предназначена для работы.

Не существует «лучшей практики» для привязки элементов управления пользователя к свойствам, определенным на его поверхности. Это зависит. Однако использование стиля для этого кажется странным.Вы можете просто указать корень UserControl x:Name="root", а затем использовать в вашей привязке ElementName=root.

пример связывания в UserControl к собственности, определенной на UserControl (взято из старого прототипа) ...

Вот UserControl предназначена для добавления или удаления списка вещей.

  • DependencyProperties, определенные на UserControl
  • привязок внутри UserControl, которые связываются с этими свойствами

Я не гарантирую это работает, но это будет показано, как это делается:

public partial class ItemsEditor : UserControl 
{ 
    #region Items 
    public static readonly DependencyProperty ItemsProperty = 
     DependencyProperty.Register(
      "Items", 
      typeof(IEnumerable<Item>), 
      typeof(ItemsEditor), 
      new UIPropertyMetadata(null)); 
    public IEnumerable<Item> Items 
    { 
     get { return (IEnumerable<Item>)GetValue(ItemsProperty); } 
     set { SetValue(ItemsProperty, value); } 
    } 
    #endregion 
    #region AddItem 
    public static readonly DependencyProperty AddItemProperty = 
     DependencyProperty.Register(
      "AddItem", 
      typeof(ICommand), 
      typeof(ItemsEditor), 
      new UIPropertyMetadata(null)); 
    public ICommand AddItem 
    { 
     get { return (ICommand)GetValue(AddItemProperty); } 
     set { SetValue(AddItemProperty, value); } 
    } 
    #endregion   
    #region RemoveItem 
    public static readonly DependencyProperty RemoveItemProperty = 
     DependencyProperty.Register(
      "RemoveItem", 
      typeof(ICommand), 
      typeof(ItemsEditor), 
      new UIPropertyMetadata(null)); 
    public ICommand RemoveItem 
    { 
     get { return (ICommand)GetValue(RemoveItemProperty); } 
     set { SetValue(RemoveItemProperty, value); } 
    }   
    #endregion 
    public ItemsEditor() 
    { 
     InitializeComponent(); 
    } 
} 

Он просто перечисляет кучу вещей, вы можете добавить новую вещь или удалить вещь из списка. Вот привязки в XAML

<UserControl x:Class="LolPrototype.ItemsEditor" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:t="clr-namespace:UCsAndICommands" 
      x:Name="root"> 
    <UserControl.Resources> 
     <DataTemplate DataType="{x:Type t:Item}"> 
      <StackPanel Orientation="Horizontal"> 
       <Button Command="{Binding RemoveItem, ElementName=root}" 
         CommandParameter="{Binding}">Remove</Button> 
       <TextBox Text="{Binding Name}" Width="100"/> 
      </StackPanel> 
     </DataTemplate> 
    </UserControl.Resources> 
    <StackPanel> 
     <Button Command="{Binding AddItem, ElementName=root}">Add</Button> 
     <ItemsControl ItemsSource="{Binding Items, ElementName=root}" /> 
    </StackPanel> 
</UserControl> 

Очевидно, что вы можете определить DataTemplates вне списка ресурсов предка. Дело в том, чтобы показать, как привязки ElementName могут использоваться для привязки к свойствам, определенным в UserControl.

+0

Но где/как сделать этот «root» 'привязка для 'UserControl'? –

+0

@ AlyEl-Haddad ' Will

+0

Я имею в виду привязку, а не атрибут 'x: Name'. –

Смежные вопросы