Привязка IsEnabled к родительскому ViewModel вместо UserControl ViewModel - PullRequest
3 голосов
/ 21 марта 2011

Я разработал пользовательский элемент управления в 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 дочернего элемента управления.

Ответы [ 5 ]

6 голосов
/ 26 марта 2011

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

<ContentControl IsEnabled="{Binding CanModify}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
    <localControls:TeamEmployeeSelector DataContext="{Binding Confidentiality}"/>
</ContentControl>
1 голос
/ 27 марта 2011

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

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

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

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

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

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

0 голосов
/ 28 марта 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  
0 голосов
/ 26 марта 2011
<localControls:TeamEmployeeSelector Grid.Row="1" Grid.Column="0"
Grid.ColumnSpan="2" IsEnabled="{Binding ElementName=SomeElementName_With_Parent_ViewModel, Path=DataContext.CanModify}" DataContext="{Binding Confidentiality}"/>
0 голосов
/ 22 марта 2011

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

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

Надеюсь, это поможет!

...