Pregunta

Background


As the title states, I have a Custom User Control. I am using Silverlight 4, but I'm pretty sure this applies to WPF as well. The goal is to create a control that will give options to DEVs to show only the parts of the control they want displayed on a particular page, along with formatting, alignment, control alternate text, and orientation properties.

The pieces that are to be shown are:

  • Country
  • SubdivisionCategory ( State, District, Outlying Territory )
  • SubdivisionCensusRegion ( Northeast, South, Midwest, West )
  • SubdivisionCensusDivision ( East North Central, East South Central, etc. )
  • Subdivision

I am simply trying to access the values of the properties that are set when a DEV creates an instance of this control in XAML. I have set up custom DependencyProperty objects for each property that I thought were for this purpose.


Problem


My problem is that during SetMargins() all of the this.ShowXxx properties are equal to the value that was set in the new PropertyMetadata(true) portion of the DependencyProperty.Register method signature. Therefore, the margins are not being set correctly.


Question


How can I get the initial XAML value of the this.ShowXxx properties or any other property that I have set in XAML?


Code


Here's an example of the XAML markup:

<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" />

Here's an example of the ShowCountry property:

#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

Here is the SetMargins() method:

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++;
    }
}
¿Fue útil?

Solución

Answer


For my specific example above, what I had to do was create a PropertyChangedCallback called OnShowCountryPropertyChanged and from there I could set the property to the NewValue, which, initially, was the value that was assigned in XAML.

To wire this callback up, I simply had to update the PropertyMetadata Constructor of my DependencyProperty adding to the default value, a reference to my callback.

Old Signature: new PropertyMetadata(true)

New Signature: new PropertyMetadata(true, OnShowCountryPropertyChanged)

Once I did those two things, the XAML value was being used when the getter for the property was accessed in my SetMargins() method.


Update Code


#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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top