Привязка пользовательских элементов управления на itemspaneltemplate

У меня проблемы с привязкой к пользовательскому свойству зависимости в пользовательском контроле к моей MVVM ViewModel. Мой пользовательский элемент управления работает правильно, когда я использую его непосредственно в моем представлении:

    <local:CustomControl Mode="{Binding Mode, Mode=TwoWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Grid.Row="0">
        <Button x:Name="InfoBox1" Content="Test1" />
        <Button x:Name="InfoBox2" Content="Test2" />
    </local:CustomControl>

Но при использовании его в качестве элемента панели элементов привязка не работает:

    <ItemsControl Grid.Row="0" ItemsSource="{Binding Equipment}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <local:CustomControl Mode="{Binding Mode, Mode=TwoWay}"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                ...
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Я попытался использовать RelativeSource и найти itemscontrol/view и установить путь к Mode или DataContext.Mode, но я просто не могу заставить работать привязку.

Режим определяется как:

    public static readonly DependencyProperty ModeProperty;

    public Modes Mode
    {
        get { return (Modes)this.GetValue(ModeProperty); }
        set { this.SetValue(ModeProperty, value); }
    }

и зарегистрированы в конструкторе пользовательского элемента управления:

    public CustomControl()
    {
        Mode = Modes.Default;
    }

    static CustomControl()
    {
        ModeProperty = DependencyProperty.Register("Mode", typeof(Modes), typeof(CustomControl), new FrameworkPropertyMetadata(Mode.Default, OnModeChanged));
    }

    private static void OnModeChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        CustomControl ctrl= o as CustomControl ;
        if (ctrl== null) return;

        Modes mode = (Modes)e.NewValue;
        ctrl.Mode = mode;
    }

Нужно ли использовать обходной путь, чтобы элемент управления работал как шаблон панели, или я просто слишком плохо испортил привязку?

----Редактировать

Часть модели представления:

    private Modes _mode= Modes.Default;
    public Modes Mode
    {
        get { return _mode; }
        set { _mode= value; NotifyPropertyChanged(); }
    }

    private ObservableCollection<EquipmentViewModel> _equipment;
    public ObservableCollection<EquipmentViewModel> Equipment
    {
        get { return _equipment; }
        set { _equipment = value; NotifyPropertyChanged(); }
    }

---- Edit2: я исследовал дальше, и я более сложный. Я добавил следующее к элементу управления ItemsPanelTemplate и к элементу непосредственно в сетке.

 Visibility="{Binding Visible, Converter={StaticResource visibilityConverter}}"

Изменение этого логического значения Visible работает в обоих случаях. Так что, похоже, это проблема только с пользовательским DependencyProperty.

Проверка визуального дерева DataContext элемента управления как ItemsPanelTemplate также является правильной.

Что может заставить свойство зависимости работать должным образом при прямом использовании, а не при использовании в качестве элемента itempaneltemplate?

1 ответ

Решение

Нашли, что вызывало странное противоречивое поведение. Я устанавливал свойство на определенное значение в обычном ctor

public CustomControl()
{
    Mode = Modes.Default;
}

Это, по-видимому, вызывало конфликт при использовании элемента управления в качестве элемента Itempanel. Удаление этого сделало обязательную работу как ожидалось.

Я полагаю, что разница в поведении имеет отношение к вызовам конструктора в разное время?

Другие вопросы по тегам