I'm trying to create "Expander" usercontrol that facilitates hiding (collapsing) another UI.
Now I have this:
Expander usercontrol - XAML:
<StackPanel>
<TextBlock Text="{Binding Caption, ElementName=root}"/>
<ToggleButton Content="{Binding ToggleText}" IsChecked="{Binding Expanded}"/>
<ContentControl Visibility="{Binding Expanded, Converter={x:Static root:GlobalConverters.BoolToCollapsedVisibilityConverter}}" Content="{Binding Content, ElementName=root}" />
</StackPanel>
Expander usercontrol - Code behind:
public Expander()
{
InitializeComponent();
DataContext = new ViewModels.ExpanderViewModel();
}
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption", typeof(string), typeof(Expander), new PropertyMetadata("unkown caption"));
public string Caption
{
get => (string)GetValue(CaptionProperty);
set => SetValue(CaptionProperty, value);
}
public new static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("ItemsSource", typeof(object[]), typeof(Expander), new PropertyMetadata(Array.Empty<EmptyContent>()));
public new object[] Content
{
get => (object[])GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
Expander usage - View:
<DataTemplate DataType="{x:Type viewModels:OrdersListModeViewModel}">
<StackPanel>
<controls:Expander Caption="Orders">
<ItemsControl ItemsSource="{Binding Orders}" />
</controls:Expander>
</StackPanel>
</DataTemplate>
I'm facing two issues:


As already suggested, you would have to override the
ControlTemplateso that the client of your control can use theContentproperty to define the actual content you want to host. Then you simply toggle the visibility of theContentPresenter.To enable customization, I recommend creating a custom control that extends
HeaderedContentControlinstead of using aUserControl.HeaderedContentControlgives you aHeaderproperty and aContentproperty - exactly what you want.However, because there already is a framework
Expandercontrol (that also extendsHeaderedContentControl), you should extendExpanderinstead and add additional functionality to the existing one:MyExpander.cs
Every control must never depend on its data context. A control must be data context agnostic. If you need external data then you must request it via public dependency properties. Internal elements will bind to those dependency properties to fetch their data.
This way the client of your control has full control over the
DataContextand is able to feed the required data via data binding - without any surprises (for example, bindings fail because the control internally changes theDataContext!).Generic.xaml
Example template. Only needed when the default style is explicitly overridden from the static constructor. You can see how the
ContentPresenteris collapsed or visible based on theExpander.IsExpandedproperty:MainWindow.xaml