Reputation: 133
I'm trying to create a WPF window that has a single control and 2 buttons displayed. The control can be either a TextBox, ComboBox or Slider dependent on the type of object selected to launch this window.
Is it possible to do this or will I have to create a window with 3 conrtols and manipulate their position at runtime?
Regards
Tony
additions to original question
My implementation is as follows
<Window.Resources>
<Style TargetType="TextBox" x:Key="TextBoxTemplate">
<Setter Value="{Binding ElementName=MyWindow, Path=m_csValue}" />
</Style>
<Style TargetType="{x:Type ComboBox}" x:Key="ComboBoxTemplate">
<Setter Value="{Binding ElementName=MyWindow, Path=ItemsForSelection}" />
</Style>
<Style TargetType="{x:Type Slider}" x:Key="SliderTemplate">
<Setter Value="{Binding ElementName=MyWindow, Path=SliderDetail}" />
</Style>
<Style TargetType="{x:Type ContentControl}" x:Key="DisplayValues">
<!-- Default Template -->
<Setter Property="ContentTemplate" Value="{StaticResource TextBoxTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MyWindow, Path=eType}" Value="{x:Static local:eTagDisplay.Text}">
<Setter Property="ContentTemplate">
<Setter.Value>
<ControlTemplate Template="{StaticResource TextBoxTemplate}" />
</Setter.Value>
</Setter>
</DataTrigger>
<!-- DataTrigger Binding="{Binding ElementName=MyWindow, Path=eType}" Value="{x:Static local:eTagDisplay.Combo}">
<Setter Property="ContentTemplate">
<Setter.Value>
<ControlTemplate Template="{StaticResource ComboBoxTemplate}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=MyWindow, Path=eType}" Value="{x:Static local:eTagDisplay.Slider}">
<Setter Property="ContentTemplate">
<Setter.Value>
<ControlTemplate Template="{StaticResource SliderTemplate}" />
</Setter.Value>
</Setter>
</DataTrigger -->
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Width="267">
<StackPanel Name="TagEditor1">
<!-- Text="{Binding ElementName=MyWindow, Path=m_csValue}" / -->
<ContentControl Style="{StaticResource DisplayValues}" />
</StackPanel>
<Button Content="OK" Height="23" HorizontalAlignment="Left" Margin="12,154,0,0" Name="btnOK" VerticalAlignment="Top" Width="75" Click="OnClkOK" />
<Button Content="Cancel" Height="23" HorizontalAlignment="Left" Margin="180,154,0,0" Name="btnCancel" VerticalAlignment="Top" Width="75" Click="OnClkCancel" IsCancel="True" />
</Grid>
I'm getting an error 'System.Windows.Style' is not a valid value for the 'System.Windows.Controls.ContentControl.ContentTemplate' property on a setter. I don't know why this is happening. My Binding is OK, i believe, as it picks up string OK....
Upvotes: 1
Views: 436
Reputation: 132618
I would do this with a <ContentControl>
that has a different <ContentTemplate>
depending on what type of control is needed.
You didn't specify how the control type is being passed to the window, so your DataTrigger
bindings would probably look a bit different from mine, but this should give you the right idea:
<DataTemplate TargetType="{x:Type ContentControl}" x:Key="TextBoxTemplate">
<TextBox ... />
</DataTemplate>
<DataTemplate TargetType="{x:Type ContentControl}" x:Key="ComboBoxTemplate">
<ComboBox ... />
</DataTemplate>
<DataTemplate TargetType="{x:Type ContentControl}" x:Key="SliderTemplate">
<Slider ... />
</DataTemplate>
<Style x:Key="MyStyle" TargetType="{x:Type ContentControl}">
<!-- Default Template -->
<Setter Property="ContentTemplate"
Value="{StaticResource TextBoxTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding SomeBoundValue}" Value="ComboBox">
<Setter Property="ContentTemplate"
Value="{StaticResource ComboBoxTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding SomeBoundValue}" Value="Slider">
<Setter Property="ContentTemplate"
Value="{StaticResource SliderTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
...
<ContentControl Style="{StaticResource MyStyle}" />
You could also allow users to specify a Content
for your UserControl
or Window
, and simply display it using a ContentPresenter
bound to the Content
. Something like this:
<UserControl.Template>
<StackPanel>
<ContentPresenter Content="{TemplateBinding Content}" />
<Button ... />
<Button ... />
</StackPanel>
</UserControl.Template>
then you could use it like this:
<local:MyUserControl>
<TextBox ... />
</local:MyUserControl>
<local:MyUserControl>
<ComboBox ... />
</local:MyUserControl>
<local:MyUserControl>
<Slider ... />
</local:MyUserControl>
Upvotes: 3
Reputation: 176
I think it is possible with single window.By exposing a property that sets visibilty based on some condition. i.e textbox visibility is set to visibility.visible and combobox,slider visibilty is set to visibility.collpased.similarly if you want to have combobox visible you make that visible and others collapsed.similarly for slider.
example:
public Visibility TextboxVisibility
{
set
{
Visibility visible = value;
Textboxname.Visibility = visible ;
}
}
I hope this answers your question
Upvotes: 1