Exposing Inherited Members
I have a WPF Custom Control library (ContentToggleButton
) and an app (spec
) to test it. The Custom Controls, which derive from Presentation Framework elements, expose inherited properties as well as new properties to the consumer.
This means that the consuming app depends on the Framework Elements as well as the Custom Controls as shown by the four dependencies from the top and bottom of MainWindow
in the following diagram.
Reimplementing Inherited Members
The references were due to the IsChecked
dependency property of the ToggleButton
base class of the ContentToggle
object and the Click
event of the ButtonBase
base class of the ButtonContent
object. The former was bound in the XAML to a method on the MainWindow
class in the View, code behind.
<b:ContentToggle Name="Toggle" Height="30"
Options="{Binding ToggleButtonView.Options,
RelativeSource={StaticResource View}}"
IsChecked="{Binding ToggleButtonView.InitialState,
Mode=OneWay,
RelativeSource={StaticResource View}}" />
<b:ContentButton x:Name="Plain" Height="30"
Options="{Binding PlainButtonView.Options,
RelativeSource={StaticResource View}}" />
The RelativeSource
resource is defined in Resource Dictionary in App.xaml.
<!--Get a reference to the window to establish View Context-->
<RelativeSource x:Key="View" Mode="FindAncestor"
AncestorType="{x:Type Window}" />
The second dependency was due to subscribing to the Click
event inherited from ButtonBase
in the MainWindow
class.
Plain.Click += (s, e) => {
Toggle.IsEnabled = !Toggle.IsEnabled;
};
By adding a custom DP called InitialState
on ContentToggle
and binding to that instead then using it to initialise IsChecked
in the Loaded event, one of the dependencies was eliminated.
public static readonly DependencyProperty
InitialStateProperty = DependencyProperty.Register(
"InitialState", typeof(bool?), typeof(ContentToggle),
new PropertyMetadata(false));
public bool? InitialState
{
get { return (bool?) GetValue(InitialStateProperty); }
set { SetValue(InitialStateProperty, value); }
}
The second dependency was eliminated by reimplementing the Click
event in the custom property and routing the original event through it.
public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent(
"Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ContentToggle));
public new event RoutedEventHandler Click
{
add { AddHandler(ClickEvent, value); }
remove { RemoveHandler(ClickEvent, value); }
}
void RaiseClickEvent (object o, RoutedEventArgs e)
{
RoutedEventArgs newEventArgs = new RoutedEventArgs(ContentToggle.ClickEvent);
RaiseEvent(newEventArgs);
}
public ContentToggle()
{
base.Click += RaiseClickEvent;
}
As a result, the consuming app is unaware of the primitive components with dependencies only on the CC Library.
Is this a good idea or a bad one? Is it worth the extra code?