4

バックグラウンド


タイトルが示すように、カスタム ユーザー コントロールがあります。私は Silverlight 4 を使用していますが、これは WPF にも当てはまると確信しています。目標は、開発者が特定のページに表示したいコントロールの部分のみを表示するオプションを開発者に提供するコントロールを作成することです。これには、書式設定配置コントロールの代替テキスト、および向きのプロパティも含まれます。

展示予定の作品は次のとおりです。

  • Country
  • SubdivisionCategory(州、地区、周辺地域)
  • SubdivisionCensusRegion(北東、南、中西部、西部)
  • SubdivisionCensusDivision(東北中央、東南中央など)
  • Subdivision

DEV が XAML でこのコントロールのインスタンスを作成するときに設定されるプロパティの値にアクセスしようとしているだけです。DependencyPropertyこの目的のために、各プロパティにカスタム オブジェクトを設定しました。


問題


私の問題は、SetMargins()すべてのプロパティがメソッド署名の部分this.ShowXxxに設定された値と等しいことです。したがって、余白が正しく設定されていません。new PropertyMetadata(true)DependencyProperty.Register


質問


this.ShowXxxXAML で設定したプロパティまたはその他のプロパティの初期 XAML 値を取得するにはどうすればよいですか?


コード


XAML マークアップの例を次に示します。

<local:CountryAndSubdivisionFilter 
    x:Name="ReportSettingsCountryAndSubdivisionFilter"
    Orientation="Horizontal"
    CountryFormat="Name"
    SubdivisionFormat="Name"
    ShowCountry="False"
    ShowSubdivisionCategory="False"
    ShowSubdivisionCensusRegion="False"
    ShowSubdivisionCensusDivision="True"
    ShowSubdivision="True"
    SubdivisionCensusDivisionText="Region"
    SubdivisionText="State"
    Margin="0,15,0,0" />

ShowCountryプロパティの例を次に示します。

#region ShowCountry
public static readonly DependencyProperty ShowCountryProperty = DependencyProperty.Register
(
    "ShowCountry",
    typeof(bool),
    typeof(CountryAndSubdivisionFilter),
    new PropertyMetadata(true)
);
public bool ShowCountry
{
    get
    {
        return (bool) GetValue(ShowCountryProperty);
    }
    set
    {
        SetValue(ShowCountryProperty, value);

        this.CountryStackPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
        this.SetMargins();
    }
}
#endregion

SetMargins()メソッドは次のとおりです。

private void SetMargins()
{
    this.CountryStackPanel.Margin = new Thickness(0);
    this.SubdivisionCategoryStackPanel.Margin = new Thickness(0);
    this.SubdivisionCensusRegionStackPanel.Margin = new Thickness(0);
    this.SubdivisionCensusDivisionStackPanel.Margin = new Thickness(0);
    this.SubdivisionStackPanel.Margin = new Thickness(0);

    var spList = new List<StackPanel>();

    if (this.ShowCountry)
        spList.Add(this.CountryStackPanel);

    if (this.ShowSubdivisionCategory)
        spList.Add(this.SubdivisionCategoryStackPanel);

    if (this.ShowSubdivisionCensusRegion)
        spList.Add(this.SubdivisionCensusRegionStackPanel);

    if (this.ShowSubdivisionCensusDivision)
        spList.Add(this.SubdivisionCensusDivisionStackPanel);

    if (this.ShowSubdivision)
        spList.Add(this.SubdivisionStackPanel);

    int spIndex = 1;
    foreach(var sp in spList)
    {
        var i = (spIndex < spList.Count) ? 15 : 0;
        var j = (spIndex == 1) ? 0 : 15;

        sp.Margin = (this.Orientation == Orientation.Horizontal)
                        ? new Thickness(0, 0, i, 0) 
                        : new Thickness(0, j, 0, 0);

        spIndex++;
    }
}
4

1 に答える 1

4

答え


上記の特定の例では、PropertyChangedCallback呼び出された を作成しOnShowCountryPropertyChanged、そこからプロパティを に設定する必要がありましたNewValue。これは、最初は XAML で割り当てられた値でした。

このコールバックを接続するには、コールバックへの参照であるデフォルト値への追加をPropertyMetadata Constructor更新するだけで済みました。DependencyProperty

古い署名: new PropertyMetadata(true)

新しい署名: new PropertyMetadata(true, OnShowCountryPropertyChanged)

これら 2 つのことを行うと、SetMargins()メソッドでプロパティのゲッターにアクセスしたときに XAML 値が使用されていました。


コードの更新


#region ShowCountry
public static readonly DependencyProperty ShowCountryProperty = DependencyProperty.Register
(
    "ShowCountry",
    typeof(bool),
    typeof(CountryAndSubdivisionFilter),
    new PropertyMetadata(true, OnShowCountryPropertyChanged)
);
public bool ShowCountry
{
    get
    {
        return (bool) GetValue(ShowCountryProperty);
    }
    set
    {
        SetValue(ShowCountryProperty, value);

        this.CountryStackPanel.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
        this.SetMargins();
    }
}
private static void OnShowCountryPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var ctrl = d as CountryAndSubdivisionFilter;
    ctrl.ShowCountry = (bool) e.NewValue;
}
#endregion
于 2013-12-19T19:58:18.813 に答える