Привязка IsEnabled к родительской ViewModel вместо ViewModel UserControl

Я разработал пользовательский элемент управления в SilverLight, который содержит несколько дочерних элементов управления. Textboxes, ComboBoxes и так далее.

Проблема в том, что когда я включаю этот UserControl в родительский вид и устанавливаю полный элемент управления на IsEnabled=False, дочерние элементы управления в этом конкретном UserControl все еще активны.

В конце концов я нашел проблему.

Добавление чего-то в этом роде подразумевает, что привязка IsEnabled находится в привязке UserControl, а не так, как ожидалось от меня в DataContext родительского элемента.

<localControls:TeamEmployeeSelector Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
          IsEnabled="{Binding CanModify}" DataContext="{Binding Confidentiality}"/>

ВОПРОС:
Но все еще остается вопрос, как привязать IsEnabled к ViewModel родительского элемента? Потому что копировать свойство CanModify в ViewModel дочернего элемента управления не очень элегантно.


person BitKFu    schedule 21.03.2011    source источник


Ответы (4)


Вместо того, чтобы каким-либо образом изменять привязку (например, вы можете сделать ее зависимой от другого имени элемента управления, как это предлагается в другом ответе), я бы переместил отдельный элемент управления, который будет отключен, и элемент управления, где будет изменено DataContext. Например:

<ContentControl IsEnabled="{Binding CanModify}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
    <localControls:TeamEmployeeSelector DataContext="{Binding Confidentiality}"/>
</ContentControl>
person Snowbear    schedule 26.03.2011
comment
Привет, Snowbear, это подходящее решение. Я попробую завтра. Спасибо за подсказку. - person BitKFu; 28.03.2011

Вот как я бы это сделал.

Ваш TeamEmployeeSelector UserControl будет содержать единственный элемент корневого уровня, который по умолчанию является Grid и имеет имя "LayoutRoot".

Теперь вы можете привязать свойство IsEnabled всех дочерних элементов к UserControl следующим образом: -

 <TextBox IsEnabled="{Binding Parent.IsEnabled, ElementName=LayoutRoot}" ... />

Используя привязку элемента к элементу, вам не нужно копировать свойство CanModify в дочерние модели представления.

Кто-то может предложить вам просто добавить x:Name в свой элемент UserControl, а затем выполнить привязку непосредственно к нему, а не использовать свойство Parent корневого элемента, как я делал выше. Это нормально работает в Silverlight 4, но не в 3 или WP7. Лично я предпочитаю вышеуказанное.

person AnthonyWJones    schedule 27.03.2011
comment
Привет, Anothony, я не пробовал ваше решение прямо сейчас, но похоже, что оно не решает проблему, в которой должно быть расположено свойство CanModify. Проблема не в том, чтобы отключить дочерние элементы управления пользовательского элемента управления, а в том, чтобы отключить сам пользовательский элемент управления. Эта привязка UserControl IsEnabled зависит от свойства CanModify, которое действительно должно быть расположено в модели представления элемента управления. Этот момент меня раздражает ... - person BitKFu; 28.03.2011

Это проблема определения объема. Как правило, при создании UserControl вы хотите установить себя как DataContext для его подэлементов. Проще всего это сделать в конструкторе:

UserControlExample() {
   InitializeComponent();
   RootElement.DataContext = this;
}

Где RootElement - это имя, которое вы даете этому первому дочернему элементу (обычно сетке или панели) вашего UserControl.

Отсюда вы можете установить естественные привязки для своих подэлементов, например:

<TextBox x:Name="MainTextBox" IsEnabled={Binding IsEnabled} />

Это работает, поскольку TextBox наследует DataContext родительской панели макета.

Наконец, если вы хотите, чтобы ваше свойство UserControl IsEnabled было связано с его родительским элементом, это лучше всего сделать в момент объявления:

<Grid>
   <UserControlExample IsEnabled={Binding CanModify} />
</Grid>

Таким образом, вы разделите свои проблемы. Субэлементам управления все равно, что отражает UserControl. Им просто нужно знать, как включить / отключить, когда свойство IsEnabled элемента управления переворачивается.

sub-controls IsEnabled bound to --> (UserControlExample is DataContext)
   UserControlExample.IsEnabled bound to -->  (VM is DataContext)
      VM.CanModify  
person cunningdave    schedule 27.03.2011

Я не знаю, возможно ли это в Silverlight, но в WPF я бы использовал RelativeSource.

Посмотрите здесь.

Надеюсь на эту помощь!

person Vivien Ruiz    schedule 22.03.2011