XAML: привязка свойства в DataTemplate

Я довольно новичок в XAML, но наслаждаюсь его изучением. Что меня действительно напрягает, так это привязка свойства к элементу DataTemplate.

я создал простой пример WPF, чтобы (надеюсь) объяснить мою проблему.

я этот пример я пытаюсь связать Visibility свойства CheckBox на DataTemplate к свойству в моей viewmodel. (Используя этот сценарий исключительно для обучения / демонстрации.)

у меня есть простая DataModel с именем Item, но это мало значения в этом примере.

class Item : INotifyPropertyChanged
{

    // Fields...
    private bool _IsRequired;
    private string _ItemName;

и довольно простая модель представления с именем ItemViewModel.

class ItemViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Item> _Items;
    private bool _IsCheckBoxChecked;
    private bool _IsCheckBoxVisible;

    public ObservableCollection<Item> Items
    {
        get { return _Items; }
        set { _Items = value; }
    }


    public bool IsCheckBoxChecked
    {
        get { return _IsCheckBoxChecked; }
        set
        {
            if (_IsCheckBoxChecked == value)
                return;
            _IsCheckBoxChecked = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxChecked"));
                PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxVisible"));
            }
        }
    }


    public bool IsCheckBoxVisible
    {
        get { return !_IsCheckBoxChecked; }
        set
        {
            if (_IsCheckBoxVisible == value)
                return;
            _IsCheckBoxVisible = value;
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("IsCheckBoxVisible"));
        }

(конструкторы и INotifyPropertyChanged реализация опущена для краткости.)

элементы управления выложены в MainPage.xaml следующим образом.

<Window.Resources>
    <local:VisibilityConverter x:Key="VisibilityConverter"/>
</Window.Resources>

<Window.DataContext>
    <local:ItemViewModel/>
</Window.DataContext>

<Grid>
    <StackPanel>
        <CheckBox x:Name="checkBox" Content="Hide CheckBoxes"  FontSize="14"  IsChecked="{Binding IsCheckBoxChecked, Mode=TwoWay}" />
        <ListView ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch" >
            <ListView.ItemTemplate >
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding ItemName}"/>
                        <CheckBox  Grid.Column="1" Visibility="{Binding IsCheckBoxVisible, Converter={StaticResource VisibilityConverter}}"   >
                            <CheckBox.DataContext>
                                <local:ItemViewModel/>
                            </CheckBox.DataContext>
                        </CheckBox>
                    </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
       <StackPanel Orientation="Horizontal" Margin="4,4,0,0">
        <TextBlock Text="IsCheckBoxVisible:"/>
            <TextBlock Text="{Binding IsCheckBoxVisible}" Margin="4,0,0,0" FontWeight="Bold" />
        </StackPanel >
        <Button Content="Button" Visibility="{Binding IsCheckBoxVisible, Converter={StaticResource VisibilityConverter}}" Margin="4,4,4,4"/>
    </StackPanel>

</Grid>

флажок "скрыть флажки" привязан к IsCheckBoxChecked и используется для обновления IsCheckBoxVisible. Я также добавил несколько дополнительных элементов управления ниже DataTemplate чтобы доказать, (себе,) все завод.)

я также реализовал конвертер значений Джеффа Уилкокса. (Спасибо тебе.) http://www.jeff.wilcox.name/2008/07/visibility-type-converter/

когда я запускаю приложение, проверяя и снимая флажок "скрыть флажок", элементы управления вне DataTemplate функция, как ожидалось, но, увы,Checkbox внутри шаблона данных остается неизменным.

у меня был успех с:

IsVisible="{Binding IsChecked, Converter={StaticResource VisibilityConverter}, ElementName=checkBox}"

но я не просто пытаюсь имитировать другой контроль но принимайте решения, основанные на ценности.

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

спасибо.

1 ответов


когда вы находитесь в DataTemplate, ваш DataContext является шаблонным объектом данных, в этом случае Item. Таким образом, DataContext флажка в DataTemplate является Item, а не ваши ItemViewModel. Вы можете видеть это по вашему <TextBlock Text="{Binding ItemName}"/>, который привязывается к собственности на Item класса. Привязка к IsCheckBoxVisible пытается найти свойство с именем IsCheckBoxVisible на Item.

есть несколько способов обойти это, но на сегодняшний день проще всего это сделать это:

в вашем окне (в xaml) дайте ему и x:Name. Например:

<Window [...blah blah...]
        x:Name="MyWindow">

измените привязку, чтобы выглядеть так:

<CheckBox Grid.Column="1"
          Visibility="{Binding DataContext.IsCheckBoxVisible, ElementName=MyWindow, Converter={StaticResource VisibilityConverter}}">

мы используем окно в качестве источника для привязки, а затем смотрим на его свойство DataContext (которое должно быть вашим ItemViewModel, а затем снять свойство IsCheckBoxVisible.

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