views:

333

answers:

2

I have created a XAML UserControl that is used to enter the current date using some up/down controls. The interesting parts of the UserControl are as follows:

<UserControl x:Class="MyApp.Controls.DateEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uControl="clr-namespace:MyApp.Controls"
xmlns:uConverters="clr-namespace:MyApp.Converters"
x:Name="dateEntry">

etc...
Here's where the numeric up/down controls are defined

<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
    <uControl:NumericEntry x:Name="monthEntry" Label="Month" Style="{StaticResource SmallNumericEntry}" Maximum="12" Number="{Binding Path=Month, ElementName=dateEntry, Mode=TwoWay}" Minimum="1"/>
    <uControl:NumericEntry x:Name="dayEntry" Label="Day" Style="{StaticResource SmallNumericEntry}" Margin="10,0,0,0" Maximum="31" Number="{Binding ElementName=dateEntry, Path=Day, Mode=TwoWay}" Minimum="1"/>
    <uControl:NumericEntry x:Name="yearEntry" Label="Year" Style="{StaticResource LargeNumericEntry}" Margin="10,0,0,0" Maximum="9999" Number="{Binding ElementName=dateEntry, Path=Year, Mode=TwoWay}" Minimum="1"/>
</StackPanel>

You can see how certain properties of the NumericEntries are defined (e.g. For yearEntry, Maximum="9999"). Now what I want to do, is allow any anyone who uses this UserControl in their XAML code to be able to modify this property. Here's some XAML (seperate file) that uses this UserControl:

<uControl:DateEntry
            x:Name="treatmentDate"
            Date="{Binding Source={StaticResource currentTreatment}, Path=Date, Mode=TwoWay}"
            Margin="10" />

I want to override the value of yearEntry.Maximum to be 2099. However, in the XAML file that uses the UserControl, it doesn't have visibility to yearEntry. It is possible to modify this programatically in the .cs file, but this kind of definition surely belongs in the XAML file.

Thanks in advance for your responses!

+1  A: 

Anything you want to be externally visible on your UserControl generally should be a public property, event, etc, on that UserControl. Except in extremely rare situations clients should not have to drill down into the UserControl's "guts" to work with them.

In your case, you should have a MaximumYear DependencyProperty of type int declared in your UserControl. This is declared in the code-behind - use "wpfdp" template for VB or "propdp" for C# editor. (Type the template abbreviation and hit tab to get a fillable template).

Once your DependencyProperty has been created, your UserControl's XAML can bind to it:

<uControl:NumericEntry x:Name="yearEntry" Maximum="{Binding MaximumYear, ...

and your clients can use it as an ordinary property or in XAML:

dateEntry.MaximumYear = 2010;

or in the client code's XAML:

<uControl:DateEntry MaximumYear="2010" ...
Ray Burns
Perfect. Nice trick with the template abbrev.
Tim
+1  A: 

if your dateEntry class had a dependency property for maximum year, you could bind to them from any control that uses them. then your code to set the year would look like this

<uControl:NumericEntry 
  x:Name="yearEntry" 
  Label="Year" 
  Style="{StaticResource LargeNumericEntry}" 
  Margin="10,0,0,0" 
  Maximum="{Binding ElementName=dateEntry, Path=MaximumYear}" 
  Number="{Binding ElementName=dateEntry, Path=Year, Mode=TwoWay}" 
  Minimum="1"/>

and in your code behind you could set the max to 9999 in the dependency props definition

  public int MaximumYear {
     get { return (int)GetValue(MaximumYearProperty); }
     set { SetValue(MaximumYearProperty, value); }
  }

  public static readonly DependencyProperty MaximumYearProperty =
      DependencyProperty.Register("MaximumYear", typeof(int), typeof(NumericEntry), new UIPropertyMetadata(9999));

then use it like this

<uControl:DateEntry
  x:Name="treatmentDate"
  Date="{Binding Source={StaticResource currentTreatment}, Path=Date, Mode=TwoWay}"
  MaximumYear="9999"
  Margin="10" />
Aran Mulholland
Exactly what I'm looking for. Thanks.
Tim