2011-05-16 13 views
7

いくつかのカスタムセキュリティ設定に基づいて、ウィンドウの子コントロールを読み取り専用および無効に変更します。これを達成するために、ウィンドウが読み込まれるときに子コントロールをループします。WPF - 新しいビジュアル子要素が追加されたときを検出する方法は?

これはうまくいきます。 99%完璧です。

私のウィンドウには、コンボボックスに基づいた内容のItemsControlがあります。 ComboBoxを変更すると、ItemsControl内の子コントロールが再度データバインドされます。しかし、セキュリティ(読み取り専用/無効)はもはや真実ではありません。

ソリューションにジャンプする前に、ComboBox changedイベントを処理できることがわかりました。しかし、私は多くのそのようなボックスを持っており、開発者がウィンドウ/フォームに追加しても、ウィンドウレベル(思考:ベース)で適用できる汎用ソリューションはありません。

私の質問(長いリードインで申し訳ありません)は、データバインディングのような動的なアクティビティのために新しい子供がウィンドウに追加されたときをどうすれば検出できますか? NewChildAddedイベントはありますか? DataBindingJustChangedThingsイベントはありますか?

何かがあるはずです。

ソリューションにタイマーが含まれている場合は、返信する必要はありません。私のフォームは余分な負荷を処理するには複雑すぎます。また、ティック間の遅延はセキュリティ上の問題にはあまりにも現実的です。

考えているかもしれませんが、外側のコンテナを読み取り専用または無効にしてください。しかし、これはエキスパンダー、複数行のテキストボックス、リストボックスなどに悪影響を及ぼします。そのようなアプローチは粒状ではありません。もちろん、それは前に反復を開始した場所です。

ソリューションにスタイルが含まれている場合は、コントロールごとにアプローチを上書きする方法を含める必要があります。一部のコントロール(チェックボックスなど)は、UIレイアウトの目的を持っているため、無効にすることはできません。

申し訳ありませんが、制約はありますが、私は本番環境でこのソリューションを使用する予定です。

ありがとうございます。

答えて

18

OnVisualChildrenChangedを試しましたか?

+0

を、 'OnVisualChildrenChanged' Canvasの一般公開のイベントではないようです。 :(継承する時間) – IAbstract

+2

Canvas for Canvas:http://stackoverflow.com/questions/5134080/canvas-in-wpf-how-do-i-detect-when-an-element-has-been-added-removed -から –

4

非常にハックしかし、あなたは方法をOnVisualChildrenChangedオーバーライドすることはできませんので、あなたがコントロールから継承しない場合には、私のために働きました。

LayoutUpdatedイベントを聴くことができます。例怒鳴るで

、私はGridYouWantToListenToという名前の、最初の時間に私のグリッドを聴きたい1つのまたは2つの要素を追加:背後

<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 
      } 
     } 
    } 
} 
関連する問題