2011-05-16 3 views
7

Основываясь на некоторых пользовательских настройках безопасности, я изменяю дочерние элементы окна для чтения и отключения. Чтобы выполнить это, я прохожу через дочерние элементы управления, когда загружается окно.WPF - Как определить, когда добавляются новые дочерние элементы Visual?

Это работает просто отлично. 99% идеально.

В моем окне у меня есть ItemControl, содержимое которого основано на ComboBox. Измените ComboBox, дочерние элементы управления в ItemsControl снова привязаны к базе данных. Но, тогда безопасность (readonly/disabled) больше не верна.

Прежде, чем вы перейдете к решению, я знаю, что смогу обработать событие, измененное в ComboBox; но у меня есть много таких ящиков и wnt общее решение, которое может применяться на уровне окна (думаю: base) независимо от того, что мои разработчики добавляют к окну/форме.

Мой вопрос (извините за длинный ввод), как я могу определить, когда новый ребенок добавляется в окно из-за некоторой динамической активности, такой как привязка данных? Есть ли событие NewChildAdded? Есть ли событие DataBindingChangedThings?

Должно быть что-то.

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

Возможно, вы думаете, просто сделайте внешний контейнер только для чтения или отключен. Но это негативно сказывается на таких вещах, как расширители, многострочные текстовые поля и списки. Такой подход недостаточно прочен. Конечно, мы начали итерации назад.

Если ваше решение включает стиль, вам необходимо указать, как я могу переопределить ваш подход на основе управления. Некоторые элементы управления (например, флажок) не могут быть отключены, поскольку они имеют цель в макете пользовательского интерфейса.

Извините за ограничения, но я планирую использовать решение на производстве.

спасибо.

ответ

18

Вы попробовали OnVisualChildrenChanged?

+0

К сожалению, 'OnVisualChildrenChanged' не является общедоступным событием для 'Canvas'. :(Время унаследовать. – IAbstract

+2

Да для холста: http://stackoverflow.com/questions/5134080/canvas-in-wpf-how-do-i-detect-when-an-element-has-been-added-removed -из –

4

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

Вы можете прослушивать событие LayoutUpdated.

На примере сильфона, я хочу, чтобы слушать в первый раз мой Grid, названный GridYouWantToListenTo, добавьте один или два элемента:

<Window x:Class="WpfApplication23.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApplication23" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid x:Name="GridYouWantToListenTo"> 
    </Grid> 
</Window> 

код позади:

using System; 
using System.Linq; 
using System.Windows; 

namespace WpfApplication23 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      GridYouWantToListenTo.LayoutUpdated += GridYouWantToListenTo_LayoutUpdated; 
     } 

     private int _lastNumbreOfGridChildren = 0; 
     private void GridYouWantToListenTo_LayoutUpdated(object sender, EventArgs e) 
     { 
      var children = GridYouWantToListenTo 
        ?.Children 
        ?.OfType<FrameworkElement>() ?? Enumerable.Empty<FrameworkElement>(); 

      if (!children.Any()) 
      { 
       _lastNumbreOfGridChildren = 0; 
      } 

      int currentNumberOfItems = children.Count(); 

      if (_lastNumbreOfGridChildren == 0 && currentNumberOfItems == 1) 
      { 
       //Your Logic 
      } 
      else if (_lastNumbreOfGridChildren == 0 && currentNumberOfItems == 2) 
      { 
       //Your Logic 
      } 
     } 
    } 
}