niestety ContentPresenter wewnątrz ExpanderTemplate dla nagłówka jest w tej samej sieci jako strzałka, więc samo ustawienie opcji HeaderTemplate nie pomoże nam.
Za pomocą możemy zobaczyć, że ToggleButton ma elipsę - reprezentującą okrąg, ścieżkę - reprezentującą strzałkę i ContentPresenter, który wyświetla to, co ustawiono dla właściwości nagłówka.
alt text http://i42.tinypic.com/2ihlzzr.jpg
Teraz wiemy, że rzeczywisty układ Expander, istnieje kilka sposobów, możemy iść o modyfikacji. Stworzenie zupełnie nowego ControlTemplate dla Expander lub uzyskanie części, które chcemy usunąć, usunąć/ukryć.
Aktualizacja: Got luku Blend, po wygenerowaniu szablonu dla Expandera, to dość dużo właśnie wymaga przechodzi i usuwanie elipsy i ścieżki z każdego stylu ToggleButton.
<Style x:Key="ExpanderHeaderFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle SnapsToDevicePixels="true"
Margin="0"
Stroke="Black"
StrokeDashArray="1 2"
StrokeThickness="1" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderDownHeaderStyle"
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid SnapsToDevicePixels="False"
Background="Transparent">
<ContentPresenter SnapsToDevicePixels="True"
HorizontalAlignment="Left"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderRightHeaderStyle"
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid SnapsToDevicePixels="False"
Background="Transparent">
<ContentPresenter SnapsToDevicePixels="True"
HorizontalAlignment="Center"
VerticalAlignment="Top"
RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderUpHeaderStyle"
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid SnapsToDevicePixels="False"
Background="Transparent">
<ContentPresenter SnapsToDevicePixels="True"
HorizontalAlignment="Left"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpanderLeftHeaderStyle"
TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid SnapsToDevicePixels="False"
Background="Transparent">
<ContentPresenter SnapsToDevicePixels="True"
HorizontalAlignment="Center"
VerticalAlignment="Top"
RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ArrowlessExpanderTemplate"
TargetType="{x:Type Expander}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="HorizontalContentAlignment"
Value="Stretch" />
<Setter Property="VerticalContentAlignment"
Value="Stretch" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Expander}">
<Border SnapsToDevicePixels="true"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="3">
<DockPanel>
<ToggleButton FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
FontStretch="{TemplateBinding FontStretch}"
FontStyle="{TemplateBinding FontStyle}"
FontWeight="{TemplateBinding FontWeight}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
FocusVisualStyle="{StaticResource ExpanderHeaderFocusVisual}"
Margin="1"
MinHeight="0"
MinWidth="0"
x:Name="HeaderSite"
Style="{StaticResource ExpanderDownHeaderStyle}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
DockPanel.Dock="Top"
IsChecked="{Binding Path=IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" />
<ContentPresenter Focusable="false"
Visibility="Collapsed"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
x:Name="ExpandSite"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
DockPanel.Dock="Bottom" />
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded"
Value="true">
<Setter Property="Visibility"
TargetName="ExpandSite"
Value="Visible" />
</Trigger>
<Trigger Property="ExpandDirection"
Value="Right">
<Setter Property="DockPanel.Dock"
TargetName="ExpandSite"
Value="Right" />
<Setter Property="DockPanel.Dock"
TargetName="HeaderSite"
Value="Left" />
<Setter Property="Style"
TargetName="HeaderSite"
Value="{StaticResource ExpanderRightHeaderStyle}" />
</Trigger>
<Trigger Property="ExpandDirection"
Value="Up">
<Setter Property="DockPanel.Dock"
TargetName="ExpandSite"
Value="Top" />
<Setter Property="DockPanel.Dock"
TargetName="HeaderSite"
Value="Bottom" />
<Setter Property="Style"
TargetName="HeaderSite"
Value="{StaticResource ExpanderUpHeaderStyle}" />
</Trigger>
<Trigger Property="ExpandDirection"
Value="Left">
<Setter Property="DockPanel.Dock"
TargetName="ExpandSite"
Value="Left" />
<Setter Property="DockPanel.Dock"
TargetName="HeaderSite"
Value="Right" />
<Setter Property="Style"
TargetName="HeaderSite"
Value="{StaticResource ExpanderLeftHeaderStyle}" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Możemy również utworzyć AttachedProperty i ustawić zamiast tego zwinięte części strzałki i koła.
Oto nasz AttachedProperty:
public class AttachedProperties
{
#region HideExpanderArrow AttachedProperty
[AttachedPropertyBrowsableForType(typeof(Expander))]
public static bool GetHideExpanderArrow(DependencyObject obj)
{
return (bool)obj.GetValue(HideExpanderArrowProperty);
}
[AttachedPropertyBrowsableForType(typeof(Expander))]
public static void SetHideExpanderArrow(DependencyObject obj, bool value)
{
obj.SetValue(HideExpanderArrowProperty, value);
}
// Using a DependencyProperty as the backing store for HideExpanderArrow. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HideExpanderArrowProperty =
DependencyProperty.RegisterAttached("HideExpanderArrow", typeof(bool), typeof(AttachedProperties), new UIPropertyMetadata(false, OnHideExpanderArrowChanged));
private static void OnHideExpanderArrowChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
Expander expander = (Expander)o;
if (expander.IsLoaded)
{
UpdateExpanderArrow(expander, (bool)e.NewValue);
}
else
{
expander.Loaded += new RoutedEventHandler((x, y) => UpdateExpanderArrow(expander, (bool)e.NewValue));
}
}
private static void UpdateExpanderArrow(Expander expander, bool visible)
{
Grid headerGrid =
VisualTreeHelper.GetChild(
VisualTreeHelper.GetChild(
VisualTreeHelper.GetChild(
VisualTreeHelper.GetChild(
VisualTreeHelper.GetChild(
expander,
0),
0),
0),
0),
0) as Grid;
headerGrid.Children[0].Visibility = visible ? Visibility.Collapsed : Visibility.Visible; // Hide or show the Ellipse
headerGrid.Children[1].Visibility = visible ? Visibility.Collapsed : Visibility.Visible; // Hide or show the Arrow
headerGrid.Children[2].SetValue(Grid.ColumnProperty, visible ? 0 : 1); // If the Arrow is not visible, then shift the Header Content to the first column.
headerGrid.Children[2].SetValue(Grid.ColumnSpanProperty, visible ? 2 : 1); // If the Arrow is not visible, then set the Header Content to span both rows.
headerGrid.Children[2].SetValue(ContentPresenter.MarginProperty, visible ? new Thickness(0) : new Thickness(4,0,0,0)); // If the Arrow is not visible, then remove the margin from the Content.
}
#endregion
}
Ja tylko podróżowanie bezpośrednio do sieci, który zawiera „strzałkę” i treść nagłówka, zamiast próbować znaleźć kontroli według nazwy, więc to nie będzie działać dokładnie tak, jak w przypadku, gdy zmieniasz również ekspander w inną strukturę. Po znalezieniu Gridu, możemy ustawić Strzałkę i Okrąg, aby się zwinąć, i upewnić się, że Treść nagłówka jest przesunięta do końca w lewo.
Aby skorzystać z załączonego nieruchomość może po prostu ustawić go na elemencie w XAML:
<StackPanel>
<Expander x:Name="uiExpander"
local:AttachedProperties.HideExpanderArrow="True">
<Expander.Header>
<Border>
<DockPanel Width="Auto">
<TextBlock DockPanel.Dock="Left"
FontSize="16"
Text="IronRuby in Action!" />
</DockPanel>
</Border>
</Expander.Header>
<Expander.Content>
<TextBlock Text="This is the decriprion!" />
</Expander.Content>
</Expander>
<Button Content="Click to Show/Hide Expander Arrow"
Click="Button_Click" />
</StackPanel>
iw kodzie:
void Button_Click(object sender, RoutedEventArgs e)
{
uiExpander.SetValue(
AttachedProperties.HideExpanderArrowProperty,
!(bool)uiExpander.GetValue(AttachedProperties.HideExpanderArrowProperty));
}
Niesamowite odpowiedź człowieka! A także dzięki za narzędzie Mole, którego nie znałem na Mole! – azamsharp
+1 za solidną odpowiedź, która nie przykuła uwagi ani nie zasługuje na uznanie. :) –
Czy istnieje sposób, aby powiązać IsEnabled ze strzałką do wartości boolowskiej, Szukam schludnego rozwiązania, jeśli nie ma żadnych, po prostu go odstąpić. – Shimmy