Zunächst einmal bin ich ein Amateur-und Nicht-Englisch-Muttersprachler, so würde ich es begrüßen, wenn Sie ein wenig Geduld mit mir haben würde;)TabControl geerbt Custom zeigt nichts
eine andere Frage Stackoverflow Nach Ich habe ein TabControl erstellt, das sich selbst erweitert (wie ein Expander), indem es nur die Vorlage des ursprünglichen TabControls ändert, sodass ich einfach die Höhe des Steuerelements ändern kann, wenn ein Tab ausgewählt ist.
Das funktionierte perfekt, aber einige ViewModel-Eigenschaften für die Logik benötigt. Jetzt muss ich diese Kontrolle wieder verwenden und ich dachte, der bessere Weg wäre, ein CustomControl zu machen.
Das Problem, das ich habe, ist, dass die Custom sind nur lookless, sind nicht Stil angewendet, obwohl ich Stile für sie in der Generic.xaml
Datei angegeben haben, und die Build Action
Eigenschaft Page
, überarbeitet die AsemblyInfo.cs
, und verwendet die DefaultStyleKeyProperty.OverrideMetadata
im statischen Konstruktor. Alle folgenden weiteren Fragenvorschläge.
Ich denke, es wäre besser, den Code zu zeigen, den ich habe, und zu erklären, was ich mehr versucht habe, muss ich sagen, dass ich die Logik geschrieben habe, als ich das bemerkte, so dass es jetzt nicht funktioniert .
generic.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PRUEBA_TABBEDEXPANDER"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:ie="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:Core="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
xmlns:int="clr-namespace:System.Windows.Interactivity">
<SolidColorBrush x:Key="TabControlNormalBorderBrush" Color="#8C8E94"/>
<Style x:Key="TabItemFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="3,3,3,1" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="TabItemHotBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#EAF6FD" Offset="0.15"/>
<GradientStop Color="#D9F0FC" Offset=".5"/>
<GradientStop Color="#BEE6FD" Offset=".5"/>
<GradientStop Color="#A7D9F5" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9"/>
<SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1"/>
<SolidColorBrush x:Key="TabItemDisabledBackground" Color="#F4F4F4"/>
<SolidColorBrush x:Key="TabItemDisabledBorderBrush" Color="#FFC9C7BA"/>
<Style x:Key="TabItemStyle1" TargetType="{x:Type TabItem}">
<Setter Property="FocusVisualStyle" Value="{StaticResource TabItemFocusVisual}"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
<ToggleButton x:Name="Content" Content="{TemplateBinding Header}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction MethodName="ToggleButton_Click"
TargetObject="{Binding RelativeSource={RelativeSource TemplatedParent}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ToggleButton>
<!--<ContentPresenter x:Name="Content" ContentSource="Header"
HorizontalAlignment="{Binding HorizontalContentAlignment,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{Binding VerticalContentAlignment,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>-->
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemHotBackground}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value="1"/>
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemSelectedBackground}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemHotBorderBrush}"/>
</MultiTrigger>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="BorderThickness" TargetName="Bd" Value="1,0,1,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="BorderThickness" TargetName="Bd" Value="1,1,0,1"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="BorderThickness" TargetName="Bd" Value="0,1,1,1"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Top"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-2,-1"/>
<Setter Property="Margin" TargetName="Content" Value="0,0,0,1"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Bottom"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-1,-2,-2"/>
<Setter Property="Margin" TargetName="Content" Value="0,1,0,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Left"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-1,-2"/>
<Setter Property="Margin" TargetName="Content" Value="0,0,1,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Right"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-1,-2,-2,-2"/>
<Setter Property="Margin" TargetName="Content" Value="1,0,0,0"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemDisabledBackground}"/>
<Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemDisabledBorderBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TabbedExpanderTabControlStyle" TargetType="{x:Type TabControl}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Padding" Value="4,4,4,4"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/>
<Setter Property="Background" Value="#F9F9F9"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource TabItemStyle1}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<TabPanel x:Name="HeaderPanel" Grid.Column="0" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
<Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="1"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
<Setter Property="Margin" TargetName="HeaderPanel" Value="2,0,2,2"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
<Setter Property="Margin" TargetName="HeaderPanel" Value="2,2,0,2"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="1"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="0"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
<Setter Property="Margin" TargetName="HeaderPanel" Value="0,2,2,2"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TabbedExpanderStyle" TargetType="{x:Type local:TabbedExpander}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TabbedExpander}">
<Grid>
<TabControl Style="{StaticResource TabbedExpanderTabControlStyle}"></TabControl>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TabbedExpander.cs:
public class TabbedExpander : TabControl, INotifyPropertyChanged
{
static TabbedExpander()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TabbedExpander), new FrameworkPropertyMetadata(typeof(TabbedExpander)));
}
#region dependency properties
public ObservableCollection<object> ItemsS
{
get { return (ObservableCollection<object>)GetValue(ItemsSProperty); }
set { SetValue(ItemsSProperty, value); }
}
// Using a DependencyProperty as the backing store for ItemsS. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ItemsSProperty =
DependencyProperty.Register("ItemsS", typeof(ObservableCollection<object>), typeof(TabbedExpander),
new PropertyMetadata(new ObservableCollection<object>(), OnItemsSPropertyChanged));
private static void OnItemsSPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TabbedExpander control = d as TabbedExpander;
var old = e.OldValue as ObservableCollection<object>;
if (old != null)
{
// Unsubscribe from CollectionChanged on the old collection
old.CollectionChanged -= control.ItemsSCollectionChanged;
}
var n = e.NewValue as ObservableCollection<object>;
if (n != null)
{
// Subscribe to CollectionChanged on the new collection
n.CollectionChanged += control.ItemsSCollectionChanged;
}
}
private void ItemsSCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Reset) base.Items.Clear();
if (e.NewItems != null)
{
foreach (object item in e.NewItems)
{
base.Items.Add(item);
}
}
if (e.OldItems != null)
{
foreach (object item in e.OldItems)
{
base.Items.RemoveAt(e.OldStartingIndex);
}
}
}
#region public
public bool IsExpanded
{
get { return (bool)GetValue(IsExpandedProperty); }
set { SetValue(IsExpandedProperty, value); }
}
public double EXPANDER_OFFSET
{
get { return (double)GetValue(EXPANDER_OFFSETProperty); }
set { SetValue(EXPANDER_OFFSETProperty, value); }
}
public int EXPANDER_MIN_HEIGHT
{
get { return (int)GetValue(EXPANDER_MIN_HEIGHTProperty); }
set { SetValue(EXPANDER_MIN_HEIGHTProperty, value); }
}
public int EXPANDER_MAX_HEIGHT
{
get { return (int)GetValue(EXPANDER_MAX_HEIGHTProperty); }
set { SetValue(EXPANDER_MAX_HEIGHTProperty, value); }
}
public int EXPANDER_NOTEXPANDED_HEIGHT
{
get { return (int)GetValue(EXPANDER_NOTEXPANDED_HEIGHTProperty); }
set { SetValue(EXPANDER_NOTEXPANDED_HEIGHTProperty, value); }
}
public double EXPANDER_EXPANDED_HEIGHT
{
get { return (double)GetValue(EXPANDER_EXPANDED_HEIGHTProperty); }
set { SetValue(EXPANDER_EXPANDED_HEIGHTProperty, value); }
}
#endregion
#region static
public static readonly DependencyProperty IsExpandedProperty =
DependencyProperty.Register("IsExpanded",
typeof(bool),
typeof(TabbedExpander),
new PropertyMetadata(false, OnIsExpandedChanged));
private static void OnIsExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TabbedExpander control = d as TabbedExpander;
if ((bool)e.NewValue) control.Height = control.EXPANDER_EXPANDED_HEIGHT;
else control.Height = control.EXPANDER_NOTEXPANDED_HEIGHT;
}
public static readonly DependencyProperty EXPANDER_OFFSETProperty =
DependencyProperty.Register("EXPANDER_OFFSET",
typeof(double),
typeof(TabbedExpander),
new PropertyMetadata(102d, OnOffsetChanged));
private static void OnOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
public static readonly DependencyProperty EXPANDER_MIN_HEIGHTProperty =
DependencyProperty.Register("EXPANDER_MIN_HEIGHT",
typeof(int),
typeof(TabbedExpander),
new PropertyMetadata(96, OnMinHeightChanged));
private static void OnMinHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
public static readonly DependencyProperty EXPANDER_MAX_HEIGHTProperty =
DependencyProperty.Register("EXPANDER_MAX_HEIGHT",
typeof(int),
typeof(TabbedExpander),
new PropertyMetadata(400, OnMaxHeightChanged));
private static void OnMaxHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
public static readonly DependencyProperty EXPANDER_NOTEXPANDED_HEIGHTProperty =
DependencyProperty.Register("EXPANDER_NOTEXPANDED_HEIGHT",
typeof(int),
typeof(TabbedExpander),
new PropertyMetadata(30, OnNotExpandedHeightChanged));
private static void OnNotExpandedHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
public static readonly DependencyProperty EXPANDER_EXPANDED_HEIGHTProperty =
DependencyProperty.Register("EXPANDER_EXPANDED_HEIGHT",
typeof(double),
typeof(TabbedExpander),
new PropertyMetadata(100d, OnExpandedHeightChanged));
private static void OnExpandedHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
#endregion
#endregion
#region PropertyChanged
public event PropertyChangedEventHandler PropertyChanged = delegate { };
protected void NotifyPropChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.Height = this.EXPANDER_NOTEXPANDED_HEIGHT;
}
}
Und ein wenig MainWindow.xaml
zum Testen:
<Window x:Class="PRUEBA_TABBEDEXPANDER.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:PRUEBA_TABBEDEXPANDER"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:TabbedExpander TabStripPlacement="Top">
<TabItem Header="prueba1">
<TextBox Text="prueba1"/>
</TabItem>
</local:TabbedExpander>
</Grid>
Das ist mein letzter Versuch ist, mein erster Versuch die TabbedExpanderTabControlStyle
Stil direkt an die individuelle Steuerung der Änderung anzuwenden war nur die TargetType
, dann ohne habe ich versucht, die ItemsSProperty
Zugabe, sondern nur die s TabControl
‘mit vererbten ItemsSource
mit der gleichen Syntax in dem 'MainWindow.xaml` und zum Ändern der Syntax:
<Grid>
<local:TabbedExpander TabStripPlacement="Top">
<local:TabbedExpander.ItemsS>
<TabItem Header="prueba1">
<TextBox Text="prueba1"/>
</TabItem>
</local:TabbedExpander.ItemsS>
</local:TabbedExpander>
</Grid>
Neben <local:TabbedExpander.Items>
versuchen, die TabControl
zu verwenden' s geerbt Items
.
Das einzige, was arbeitete, war die Generic.xaml
als ResourceDictionary
und gilt TabbedExpanderTabControlStyle
direkt an die individuellen Steuerung zu verschmelzen ..., die ich nehme an ist nicht der richtige Weg, es zu tun ... nicht wahr? Weil ich den Stil auf jedem kundenspezifischen Steuerelement anwenden müsste, das ich meiner Anwendung hinzufügen würde ...
Ich nehme an, dass ich entweder etwas falsch mache, indem ich den Stil anwende, oder die tabitems Sammlungen benutze, aber gerade jetzt ' ? m aus Ideen :(
Jede Idee
Die Sache ist die, dass, korrigieren Sie mich, wenn ich falsch, wenn ich tun, wenn ich fügt das benutzerdefinierte Steuerelement der App hinzu Ich muss den Stil manuell auf alle Instanzen anwenden, richtig? – Nox
Entschuldigung, ich drückte Enter, ohne den Kommentar zu beenden ¬¬ ... Ich dachte, dass mit benutzerdefinierten Steuerelementen der Stil automatisch auf alle Instanzen angewendet würde, also sollte ich den Weg finden, dies zu tun. – Nox
Sollte nicht, nein. Wenn Sie keinen Schlüssel angeben, erben alle untergeordneten Elemente des Zieltyps den Stil. – Joe