3

カスタム コントロール、特に円グラフを作成中です。マークアップを次の例のようにしたい:

<c:PieChart>
    <!-- These dependency properties are never set -->
    <c:Slice Value="{Binding RedCount}" />
    <c:Slice Value="{Binding BlueCount}" />
    <c:Slice Value="{Binding GreenCount}" />
</c:PieChart>

PieChartから派生しControlます:

[ContentProperty("Slices")]
public class PieChart : Control
{
    public PieChart()
    {
        Slices = new ObservableCollection<Slice>();
    }

    public ObservableCollection<Slice> Slices { get; private set; }
}

上記の XAML により、Slicesプロパティに の 3 つのインスタンスが設定されますSlice

からのスニペットは次のSliceとおりです。

public class Slice : ContentControl
{
    public static DependencyProperty ValueProperty
        = DependencyProperty.Register(
            "Value", typeof(double), typeof(Slice),
            new PropertyMetadata((p,a) => ((Slice)p).OnValueChanged(a)));

    private void OnValueChanged(DependencyPropertyChangedEventArgs e)
    {
        // This code never called!
    }
}

問題はValueプロパティ onSliceが設定されないことです。に依存関係プロパティを置いてPieChartバインディング式をコピーすると、値が設定されるので、依存関係プロパティとバインディングの基本を理解していると確信しています。

では、依存関係プロパティで子アイテムに値を設定するにはどうすればよいでしょうか? これらのアイテムは私自身のコレクションにあるため、何らかの方法でバインドを機能させる魔法によって認識される論理ツリーに含まれていないのでしょうか?

単純な「これを行う」という回答は役に立ちますが、ここで何がうまくいかないのかを本当に理解したいので、投稿された最も洞察に満ちた説明的な回答を受け入れます.

EDIT私はそれを明確にしませんでしたが、プロパティなどを含むアンビエントオブジェクトがいくつかありDataContextますPieChartRedCount過去に、バインディングのパスにタイプミス(またはその他の間違い)があったとき実行時に VS 出力ウィンドウに警告が表示されます。この場合、何も見えません。

4

2 に答える 2

3

Sliceコントロールがビジュアル ツリーに接続されていないようです。それらは単なるメンバー変数であり、WPF は、PieChart. いくつかの可能なアプローチ:

オブジェクトを追加するためのPieChart呼び出しがあります。実行時に s がコレクションに追加またはコレクションから削除される可能性を処理する必要があります。これはかなり低レベルです: MSDN は次のようにアドバイスしています。 、、および. "AddLogicalChildSliceSliceContentControlItemsControlHeaderedItemsControl

を作りPieChartますPanelSlices はその子になりますが、プロパティは弱く型付けされていることに注意してChildrenくださいPieChart。これは本質的に悪いことでも良いことでもありません。これは設計上の考慮事項です (以下の注を参照)。しかし、それはおそらくあなたが望むものではありません。

を作成し、オーバーライドしPieChart、場合によってはコントロールを作成/尊重します。(と、、などを参照) これの優れた機能は、子コントロールを手動で作成する代わりに、と を( のように)使用できることです。(ただし、ユーザーは、XAML で作成できるのと同様に、構文ごとに XAML で fixed を作成できます)。ItemsControlGetContainerForItemOverrideIsItemItsOwnContainerOverridePrepareContainerForItemOverrideSliceListBoxListBoxItemComboBoxComboBoxItemItemsSourceDataTemplateListBoxSliceListBoxItems

ハイブリッド アプローチを検討することもできます。たとえば、ラジアル レイアウト機能を に分解しRadialLayoutPanel、パイ スライスの生成をとしてItemsControl使用するに分解します。RadialLayoutPanelItemsPanel

于 2009-04-27T21:12:56.420 に答える
0

あなたが見ている問題は、バインディングが間違ったソースを使用しようとしていることだと思います。次のようなものがうまくいくと思います:

<c:PieChart>
    <!-- These dependency properties are never set -->
    <c:Slice Value="{Binding RedCount, RelativeSource={AncestorType c:PieChart}}" />
    <c:Slice Value="{Binding BlueCount, RelativeSource={AncestorType c:PieChart}}" />
    <c:Slice Value="{Binding GreenCount, RelativeSource={AncestorType c:PieChart}}" />
</c:PieChart>

私はそれが近いと思いますが、私はかなり離れているかもしれません. 今はなかなか調べられません。しかし、それは私にはいいですね。(完全に間違っていたらごめんなさい:))

于 2009-04-27T20:47:50.897 に答える