10

DependancyPropertyユーザーコントロールの 1 つを の のWidthプロパティにバインドしようとしてColumnGridます。

次のようなコードがあります。

<Grid x:Name="MyGridName">
    <Grid.ColumnDefinitions>
        <ColumnDefinition x:Name="TitleSection" Width="100" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>...</Grid.RowDefinitions>

    <GridSplitter x:Name="MyGridSplitter" Grid.Row="0" Grid.Column="0" ... />
</Grid>

別の Usercontrol で、次のようにDependancyProperty定義しています。

public static readonly DependencyProperty TitleWidthProperty = DependencyProperty.Register("TitleWidth", typeof(int), typeof(MyUserControl));

public int TitleWidth
{
    get { return (int)base.GetValue(TitleWidthProperty); }
    set { base.SetValue(TitleWidthProperty, value); }
}

コードで Usercontrol のインスタンスを作成しているため、次のようなバインド ステートメントがあります。

MyUserControl Cntrl = new MyUserControl(/* Construction Params */);
BindingOperations.SetBinding(Cntrl , MyUserControl.AnotherProperty, new Binding { ElementName = "objZoomSlider", Path = new PropertyPath("Value"), Mode = BindingMode.OneWay });
BindingOperations.SetBinding(Cntrl , MyUserControl.TitleWidthProperty, new Binding { ElementName = "TitleSection", Path = new PropertyPath("ActualWidth"), Mode = BindingMode.OneWay });
/* Other operations on Cntrl */

定義された最初のバインディングは、実際の UIElement (この場合は Slider) へのバインディングですが、素晴らしく機能しますが、「TitleSection」(Grid で定義された ColumnDefinition) へのバインディングは失敗します。コードにブレークポイントを置き、"TitleSection" を監視すると、期待されるオブジェクトが返されます。

ax:Name'd ColumnDefinition をバインドできないのではないかと疑い始めています。グリッドの最初の列の幅の変化にどのようにバインドできるかを誰かが提案できますか?

EDIT #1 - コメントに答える

TitleWidthプロパティのセッターにブレークポイントが設定され、GridSplitter コントロールを使用して最初の列のサイズを変更すると、ブレークポイントにヒットしないという意味で、データバインディングは「失敗」します。さらに、DependancyProperty のTitleWidth変更が実行されないときに実行されると予想されるコード。

ユーザー コントロールが作成され、関数内のグリッド内の Stackpanel に追加されWindow_Loadedます。ユーザーコントロールが構築されるまでにグリッドがレンダリングされていると思います。確かに x:Name'd ElementTitleSectionは監視可能であり100、それらが構築されているとき/バインディングが発生する前の値を持っています。

編集#2 - おそらくこれと関係がありますか?

Grid ColumnDefinition ドキュメントの MSDN ページをくまなく調べていて、 GridLength()に出くわしましたが、バインディング式でこれを使用する方法がわかりません。関連する GridLengthConverter は、IValueConverter から派生していないため、バインディング コードでコンバーターとして使用できません。

私は、Grid オブジェクト内のセルの 1 つの ActualWidth プロパティに何らかの形でバインドする方向に傾いています。列定義にバインドするほどきれいには見えませんが、現時点ではそれを機能させることができません。

4

3 に答える 3

11

さて、私はちょっとした応急修理をしました、私は将来の世代のためにどのように説明します:

基本的に、2列の複数行グリッドがあり、最初の列にスプリッターが右揃えになっているため、含まれているコンテンツにより多くのスペースが必要な場合は、ユーザーがサイズを変更できます。複雑にするために、レンダリングの目的で2のcolumnSpanを持つ行のいくつかにプログラムでロードされているユーザーコントロールがあります(コンテンツは1つのセルから次のセルに「ブリード」します)。

最初の列のサイズが変更されたら、これをユーザーコントロールに反映させる必要があります。最初にColumnDefinitionにバインドしようとしましたが、実際にはボールを再生していませんでした。

修正/応急修理の方法

最初の列の予備のセルに<Label>、x:Nameを付けてaを追加し、アクセスできるようにしました。セル内にあるため、デフォルトのプロパティは「ストレッチ」で、セルを完全に塗りつぶします。スプリッターを使用して列のサイズが変更されると、サイズが変更されます。LabelのActualWidthプロパティにバインドすると、列のサイズの変更がcolumnSpannedユーザーコントロールのDependancyPropertyに正しく伝達されます。

考え

明らかに、ColumnDefinitionがActualWidth変更されたときにプロパティを持っているにもかかわらず、イベントを内部的に発生させるようには見えませんPropertyChanged(またはそれが私の推測です)。これはバグであるか、設計によるものである可能性がありますが、私にとっては、よりクリーンでないソリューションを使用する必要があったことを意味します。

于 2008-11-13T10:20:22.060 に答える
3

ColumnDefinition.Width は整数ではありません - GridLength です。GridLength を Integer に直接バインドすることはできません。コンバーターが必要です。

これは、コンバーターなしで Control の Width プロパティ (double) を ColumnDefinition の Width プロパティ (GridLength) にバインドできない理由でもあります。

于 2014-11-06T17:17:51.127 に答える
3

xaml でバインディングを設定しようとしたことがありますか。次の手順でうまくいくはずです。

<ColumnDefinition 
    x:Name="TitleSection" 
    Width="{Binding 
                Path=TitleWidth, 
                RelativeSource={RelativeSource AncestorType=MyUserControl}}" 
    />

それ以外の場合、提供したバインディング コードを見ると、間違った方向に見えます。バインディングのターゲットはグリッド列であり、ソースは依存関係プロパティである必要があります。

上記の xaml に相当するコードは次のとおりです。

BindingOperations.SetBinding(TitleSection, ColumnDefinition.WidthProperty,
    new Binding()
    {
        RelativeSource= new RelativeSource(RelativeSourceMode.FindAncestor, typeof(MyUserControl),1),
        Path = new PropertyPath("TitleWidth"),
    });

関連して、GridSplitter の使用と Width プロパティのバインドは相互に排他的です。スプリッターを使用して列のサイズを変更するとすぐに、バインドはスプリッターからの値に置き換えられます。

これは、バインディングのターゲットであるプロパティを更新することによって経験することと似ています。ターゲット値をコードで直接設定すると、基本的にバインディング オブジェクトが指定した値に置き換えられます。

于 2008-11-13T09:56:04.103 に答える