2016-08-04 11 views
1

遠くに複雑な実際のプロジェクトから小さなテストプロジェクトを作成しましたが、アイデアは同じです。両方とも同じ問題があります。FrameworkElementがContentControlのプロパティである場合のスタイリング/バインディング

私は2つのクラスAとBを持っています.AはContentControlの一種であり、BはFrameworkElementの一種です。 Aには依存性プロパティBee(Bの型)があります。 Bには依存関係プロパティText(文字列の型)があります。 Aのデフォルト値はnullで、Bのデフォルト値は "B There!"です。

私のテストウィンドウ(Window.Resources)でスタイリングを使用して、BのTextプロパティをデフォルト値以外の値に設定しています。

<Window.Resources> 
    <Style TargetType="local:B"> 
     <Setter Property="Text" Value="YO!!!"/> 
    </Style> 
</Window.Resources> 

私はBの新しいインスタンスにA.Contentを設定するとシステムがすべてを処理するため、すべてのものが最も可能性の高い魔法のように動作します。私。 Visual Studioのデザイナーでスタイル設定ツールの値を変更すると、対応するプロパティ値(B.Text)が変更されます。データのバインディングも正常に機能します。私はので、私は新しいBのインスタンスを作成し、A.Beeプロパティに設定し、このためA.Contentを使用することはできません制御することはできません理由から、私は実際には以下である必要がある何

<local:A.Content> 
    <local:B/> 
</local:A.Content> 

...

。この場合、暗黙のスタイリングとデータコンテキストの継承は機能しません。私。スタイル・セッターの値を変更すると、何も起こらず、データ・バインディングも機能しません。 A.Beeプロパティ値で

<local:A.Bee> 
    <local:B/> 
</local:A.Bee> 

私はAddLogicalChild指定し、AddVisualChildと木にBのインスタンスを入れて、データが作業を結合させるためにデータバインディングを使用するコールバックを変更しました。私。 A.Beeが設定されている場合、次のようになります(簡略化)。

private static void BeeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    A instanceOfA = d as A; 
    B newValue = e.NewValue as B; 

    Binding b = new Binding("DataContext"); 
    b.Source = instanceOfA; 

    BindingOperations.SetBinding(newValue, B.DataContextProperty, b); 

    instanceOfA.AddLogicalChild(newValue); 
    instanceOfA.AddVisualChild(newValue); 
} 

これはデータバインディングの問題を修正します。これが正しい方法であるかどうかはわかりませんが、正しく動作します。もっと良い方法があれば教えてください。ただし、スタイリングはVisual Studioのデザイナーではまだ機能しません。

Visual Studioのデザイナーでスタイル設定ツールの値を変更するとプロパティ値が変更されるように、スタイリング値にバインドする方法はありますか?

AddLogicalChild指定が使用されるまでnewValueが必要な場合ので、私は

を私はかなりそこに右のトラックにだが、ないと思いますが、まだ...、私は私のプロジェクトへのリンクを追加することができますそのリソースには、スタイルを持っていません誰かがそれをテスト/修正したい場合。ここで


は、試験溶液(Visual Studioの2013)へのリンクです:一言で言えばFEStyleTesting


、私はBクラスのインスタンスでA.Beeプロパティを設定すると同じように仕事をしたいですBクラスのインスタンスでA.Contentプロパティを設定します。私。 Visual Studio Designerを使用すると、データコンテキストとスタイルがBクラスのインスタンスに継承されます。画像で

Debugging designer


、私はデザイナーのデバッグだし、あなたが見ることができるよう、AddLogicalChild指定が呼び出された後、スタイルセッターが資源から見つけることができますが、何らかの理由でスタイルが適用されていませんデザイナーでは...そして、デザイナーにはInstantietedElementViewNodeプロパティの3番目のセッターがあります。私。ランタイムにはそこにはありません。たぶん、デザイナーがあらゆるコントロールのために追加したものかもしれません...最初の2人のセッターは、XAMLで定義されたものです(写真のために展開するのを忘れてしまった)。


テストアプリケーションでは、メッセージボックスをテスト用に使用することを明確にしています。私。私は変更する視覚的外観(Contentプロパティを使用するときに行う)を必要としません。スタイルセッター値がXAMLで変更されたときにコールバックを呼び出すだけです。ここで


は、この問題をテストする手順は、次のとおりです

  1. は、ソリューションを開きます。
  2. ソースタブページが開いていないことを確認してください。
  3. 場合によってはソリューションを再構築してください。
  4. MainWindow.xamlを開きます(ダブルクリックします)。
  5. メッセージボックスが表示されたら「OK」ボタンをクリックしてください。
  6. 「これらは機能しません」の最初の割り当てがコメント解除され、他の3つはコメントアウトされていることを確認してください。 (何らかの理由でこのリストのソースコードを取得できません...)
  7. Textプロパティのスタイル設定ツールの値を、 "YO2 !!!"
  8. "TextChanged"メッセージボックスは、値を編集した後に表示されます(ただし、表示されません)。

IはA.Contentプロパティを使用する場合、結合およびスタイル継承データを検証することができるように、Bは、目的に(およびいないFrameworkElementから)ContentControlに由来します。 ContentControlはFrameworkElementから派生し、結果は同じになるはずです。私の大きなプロジェクトではFrameworkElementが使用されています。


Debugging style value change.

デザイナーをデバッグしている間、私は "YOを!!!" に変更「YO2 !!!」にXAMLでB.Colorを明示的に変更しました。 ColorChangedコールバックで、私はBインスタンスのリソースを見て、値がそれに応じて変化していることに気付きました。そのため、スタイリング値はXAMLで変更すると更新されますが、何らかの理由でプロパティ値が変更されません(テキストは "YO !!!"です)。したがって、コールバックは呼び出されません。

私は可能な解決策を発見したことがあり


...これが発生する可能性がありますのだろうか。 AddLogicalChildを呼び出しても、A.LogicalChildrenにはBオブジェクトが含まれていないことに気付きました。次に、オーバーライド可能なメソッドを実行し、オーバーライド可能なLogicalChildrenプロパティを実行しました。これは、「究極」のソリューションですが、今、私のプロパティ変更コールバックが、私はスタイルセッターの値を変更するたびに呼び出された場合

protected override IEnumerator LogicalChildren 
{ 
    get 
    { 
     List<object> list = new List<object>(); 

     while (base.LogicalChildren.MoveNext() == true) 
     { 
      try 
      { 
       list.Add(base.LogicalChildren.Current); 
      } 
      catch 
      { 
       // If Current fails, break. 
       break; 
      } 
     } 

     list.Add(Bee); 

     return list.GetEnumerator(); 
    } 
} 

わからない:

ここに私のバージョンです。まあ、生きて学びなさい...これをもう少しよくテストしてください。

+0

A .. A.Bee ..問題へのあなたの試行された解決策を説明する前に、私はその点を失いました。 1つの文を使って書くことはできません。 * "どのようにスタイリング値にバインドして、Visual Studioのデザイナーでスタイル設定ツールの値を変更するとプロパティ値が変化する" * - スタイリング値は何ですか?設計時に何が起こるのかを制御したいですか?実行時に動作していますか? [mcve](http://stackoverflow.com/help/mcve)から始めてください。ここに投稿し、合理的な説明を追加します(あなたが望むものと代わりに起こるもの)。 – Sinatr

+0

スタイル値は、Window.Resourcesのスタイル設定ツールに設定された値です。あなたが理解していなければ、不平を言うことを始める前に、サンプルプロジェクトを頼みなさい、ありがとう。 – ppsmxion

+0

はい、それは実行時に動作しているので、私はVisual Studioデザイナーに言及しました。 – ppsmxion

答えて

0

したがって、問題は、LogicalChildrenプロパティをオーバーライドしてネストされたオブジェクトを含めることです。これにより、BindingOperationsをDataContextにバインドする必要もなくなります。 AddLogicalChildは依然として必要です。 AddVisualChildについてはわかりませんが、申し訳ありませんよりも安全です...

関連する問題