Один экземпляр управления делится свойством с другим? - PullRequest
1 голос
/ 18 января 2012

Я создал свою собственную панель инструментов.Внутри панели инструментов у меня есть свойство коллекции для отображения пользовательских элементов:

public static readonly DependencyProperty CustomItemsProperty =
            DependencyProperty.Register("CustomItems", typeof(List<UIElement>), typeof(DitatToolbar), new PropertyMetadata(new List<UIElement>()));

        public List<UIElement> CustomItems
        {
            get { return GetValue(CustomItemsProperty) as List<UIElement>; }
            set { this.SetValue(CustomItemsProperty, value); }
        }

На одном из моих просмотров я объявил панель инструментов с одним пользовательским элементом:

<my:DitatToolbar
            Status="{Binding State, Converter={StaticResource ViewEditingStateToToolbarStateConverter}}"
            Mode="DataEntry">
            <my:DitatToolbar.CustomItems>
                <my:DitatToolbarButton Icon="/IDATT.Infrastructure.SL;component/Images/img_btn_calculate.png" Caption="Next&#x0d;&#x0a;Number" Index="6" Command="{Binding GetNextNumberCommand}" />
            </my:DitatToolbar.CustomItems>
        </my:DitatToolbar>

По сути, я хотел разместить пользовательские "Кнопка «Получить следующий номер» на моей панели инструментов.Внутри onApplyTemplate я называю этот метод:

internal void BuildUi()
    {

    if (this.ButtonsStackPanel == null) return;

    this.defaultStatusVisibility = Visibility.Collapsed;
    this.defaultNavigationVisibility = Visibility.Collapsed;

    this.ButtonsStackPanel.Children.Clear();
    this.Items = new List<UIElement>();

    // Add buttons according to our work mode:
    switch (this.Mode)
    {
        case ModeType.Ok:
            this.Items.Add(this.GetNewButton(ButtonType.Ok));
            break;

        case ModeType.OkCancel:
            this.Items.Add(this.GetNewButton(ButtonType.Ok));
            this.Items.Add(this.GetNewButton(ButtonType.Cancel));
            break;

        case ModeType.Lookup:
            this.Items.Add(this.GetNewButton(ButtonType.CancelExit));
            this.Items.Add(this.GetNewButton(ButtonType.Ok));
            this.Items.Add(new DitatToolbarSeparator());
            this.Items.Add(this.GetNewButton(ButtonType.Refresh));
            break;

        case ModeType.DataEntry:
            this.defaultStatusVisibility = Visibility.Visible;
            this.defaultNavigationVisibility = Visibility.Visible;
            this.Items.Add(this.GetNewButton(ButtonType.CancelExit));
            this.Items.Add(this.GetNewButton(ButtonType.SaveExit));
            this.Items.Add(new DitatToolbarSeparator());
            this.Items.Add(this.GetNewButton(ButtonType.Cancel));
            this.Items.Add(this.GetNewButton(ButtonType.SaveClose));
            this.Items.Add(new DitatToolbarSeparator());
            this.Items.Add(this.GetNewButton(ButtonType.RenameId));
            this.Items.Add(this.GetNewButton(ButtonType.Delete));
            break;

        case ModeType.OptionsDataEntry:
            this.defaultStatusVisibility = Visibility.Visible;
            this.Items.Add(this.GetNewButton(ButtonType.CancelExit));
            this.Items.Add(this.GetNewButton(ButtonType.SaveExit));
            this.Items.Add(new DitatToolbarSeparator());
            this.Items.Add(this.GetNewButton(ButtonType.Save));
            break;

        default:
            throw new NotSupportedException("DitatToolbar Mode have to be specified");
    }

    if (this.Mode == ModeType.DataEntry || this.Mode == ModeType.OptionsDataEntry)
    {
        if (GetBindingExpression(CanEditProperty) == null)
        {
            this.SetBinding(CanEditProperty, new Binding("CanEdit") { Mode = BindingMode.TwoWay });
        }

        if (GetBindingExpression(CanDeleteProperty) == null)
        {
            this.SetBinding(CanDeleteProperty, new Binding("CanDelete") { Mode = BindingMode.TwoWay });
        }

        if (GetBindingExpression(CanRenameProperty) == null)
        {
            this.SetBinding(CanRenameProperty, new Binding("CanRename") { Mode = BindingMode.TwoWay });
        }
    }

    // Add custom buttons:
    foreach (var customItem in this.CustomItems)
    {
        var ci = customItem as IToolbarItem;
        this.Items.Insert(ci.Index, customItem);
    }

    // Insert buttons into container:
    foreach (var element in this.Items)
    {
        this.ButtonsStackPanel.Children.Add(element);
    }

    // Navigation panel visibility
    this.ShowNavigation();

    // Status panel visibility
    this.ChangeStatus();
}

Моя проблема в том, что по какой-то причине ВСЕ панели инструментов в моем приложении (различные представления) видят этот пользовательский элемент, который я объявил только в одном представлении.Это вызывает проблемы, очевидно.Интересно, что не так с моим кодом, что свойство зависимости CustomItem становится статическим для всего приложения?

ОТВЕТ

Свойство зависимости должно быть объявлено так:

public static readonly DependencyProperty CustomItemsProperty =
                DependencyProperty.Register("CustomItems", typeof(List<UIElement>), typeof(DitatToolbar), new PropertyMetadata(null));

И я добавил инициализацию этого свойства в конструктор:

public DitatToolbar()
        {
            this.CustomItems = new List<UIElement>();

            this.DefaultStyleKey = typeof(DitatToolbar);
        }

1 Ответ

2 голосов
/ 18 января 2012

Похоже, что значение по умолчанию, которое вы указали свойству в параметре typeMetadata (new PropertyMetadata(new List<UIElement>()), используется всеми экземплярами, т. Е. Все они будут начинаться с одного и того же пустого списка. Используйте null в качестве значения по умолчанию и вместо этого инициализируйте пустой список для каждого элемента управления в конструкторе.

...