Dies ist möglich mit einem ObjectAnimationUsingKeyFrames, aber es ist dumm zu tun, wird dazu führen, dass Sie Ihre Haare ausreißen, Ihr Visual Studio regelmäßig abstürzen und gibt Ihnen sehr wenig über die einfache Art und Weise.
Der einfache Weg:
public class TestSwapContentControl : ContentControl
{
object StoredOriginalContent;
public object FullContent
{
get { return (object)GetValue(FullContentProperty); }
set { SetValue(FullContentProperty, value); }
}
// Using a DependencyProperty as the backing store for FullContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FullContentProperty =
DependencyProperty.Register(
"FullContent"
, typeof(object)
, typeof(TestSwapContentControl)
, null);
public void SwitchToFullContent()
{
if (FullContent != null)
{
StoredOriginalContent = Content;
Content = FullContent;
}
}
public void SwitchToNormalContent()
{
if(StoredOriginalContent != null)
{
Content = StoredOriginalContent;
}
}
}
Dann wird der XAML zu verwenden:
<local:TestSwapContentControl x:Name="mySwitch">
<Rectangle Height="50" Width="100" Fill="Black" />
<local:TestSwapContentControl.FullContent>
<StackPanel>
<TextBlock>1</TextBlock>
<TextBlock>2</TextBlock>
<TextBlock>3</TextBlock>
<TextBlock>4</TextBlock>
<Rectangle Height="50" Width="100" Fill="Red" />
</StackPanel>
</local:TestSwapContentControl.FullContent>
</local:TestSwapContentControl>
Mit folgendem cs auf der Seite:
private void Button_Click(object sender, RoutedEventArgs e)
{
if (myTempBool)
{
mySwitch.SwitchToFullContent();
myTempBool = false;
}
else
{
mySwitch.SwitchToNormalContent();
myTempBool = true;
}
}
Nun, wenn Sie wirklich brauchen, um Wenn Sie die Steuerung von anderen Entwicklern vollständig erweiterbar machen, müssen Sie VisualStatemenager verwenden, aber das ist eine echte Schlampe. Wenn Sie nicht wissen, wie Visual State Manager einzurichten und Staaten durch generic.xaml, hier ist ein How-To Guide:
http://scorbs.com/2008/06/11/parts-states-model-with-visualstatemanager-part-1-of/
Hier ist ein funktionierendes Beispiel, aber es ist nicht perfekt, da ich nicht scheinen kann, um den Inhalt des ContentPresenters direkt festzulegen.
using System.Windows;
using System.Windows.Controls;
namespace SilverlightTestApplication
{
[TemplateVisualState(Name="Normal", GroupName="SizeStates")]
[TemplateVisualState(Name="Expanded", GroupName="SizeStates")]
public class TestVSMControl : ContentControl
{
public object SmallContent
{
get { return (object)GetValue(SmallContentProperty); }
set { SetValue(SmallContentProperty, value); }
}
// Using a DependencyProperty as the backing store for SmallContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SmallContentProperty =
DependencyProperty.Register("SmallContent", typeof(object), typeof(TestVSMControl), null);
public object LargeContent
{
get { return (object)GetValue(LargeContentProperty); }
set { SetValue(LargeContentProperty, value); }
}
// Using a DependencyProperty as the backing store for LargeContent. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LargeContentProperty =
DependencyProperty.Register("LargeContent", typeof(object), typeof(TestVSMControl), null);
public bool Pressed
{
get { return (bool)GetValue(PressedProperty); }
set { SetValue(PressedProperty, value); }
}
// Using a DependencyProperty as the backing store for Pressed. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PressedProperty =
DependencyProperty.Register("Pressed", typeof(bool), typeof(TestVSMControl),
new PropertyMetadata(new PropertyChangedCallback(PressedPropertyChanged)));
static void PressedPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var me = sender as TestVSMControl;
me.ChangeState();
}
public TestVSMControl()
{
DefaultStyleKey = typeof(TestVSMControl);
}
void ChangeState()
{
GoToState(true);
}
private void GoToState(bool useTransitions)
{
if (Pressed)
{
VisualStateManager.GoToState(this, "Normal", useTransitions);
}
else
{
VisualStateManager.GoToState(this, "Expanded", useTransitions);
}
}
}
}
In Ihrem generic.xaml (umfassen xmlns: VSM = "clr-namespace: System.Windows; Montage = System.Windows"):
<Style TargetType="local:TestVSMControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:TestVSMControl">
<StackPanel>
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="SizeStates">
<vsm:VisualState x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="myContentPresenter" BeginTime="00:00:00" Duration="00:00:00.0010000" >
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<StackPanel>
<TextBlock>Rararasputin</TextBlock>
<Button Content="{TemplateBinding SmallContent}" />
</StackPanel>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
<vsm:VisualState x:Name="Expanded">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content" Storyboard.TargetName="myContentPresenter" BeginTime="00:00:00" Duration="00:00:00.0010000" >
<ObjectAnimationUsingKeyFrames.KeyFrames>
<DiscreteObjectKeyFrame KeyTime="0:0:0" >
<DiscreteObjectKeyFrame.Value>
<StackPanel>
<TextBlock>Other one</TextBlock>
<Button Content="{TemplateBinding LargeContent}" />
</StackPanel>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames.KeyFrames>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="myContentPresenter" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Und wie in Ihrer Seite verwenden:
<local:TestVSMControl x:Name="myVSMControl" Height="200">
<local:TestVSMControl.SmallContent>
<Rectangle Height="50" Width="100" Fill="Red" />
</local:TestVSMControl.SmallContent>
<local:TestVSMControl.LargeContent>
<Rectangle Height="50" Width="100" Fill="Green" />
</local:TestVSMControl.LargeContent>
</local:TestVSMControl>
<Button Content="Swap" x:Name="VSMButton" Click="VSMButton_Click" />
mit der folgenden auf Ihrer Seite:
private void VSMButton_Click(object sender, RoutedEventArgs e)
{
myVSMControl.Pressed = !myVSMControl.Pressed;
}