WPF 自定義控件後如何處理新添加控件的消息

目前有個需求,寫一個類似Chrome標籤頁的界面,標籤頁上有一個+號,點擊增加標籤。+號增加了卻不知道如何處理+號的Click事件:
效果演示

首先寫Generic.xaml(其中AddItemButton就是我添加的按鈕):

    <SolidColorBrush x:Key="TabItem.Selected.Background" Color="#FFFFFF"/>
    <SolidColorBrush x:Key="TabItem.Selected.Border" Color="#ACACAC"/>
    <Style TargetType="{x:Type DIYControl:TabControlWithAddButton}">
        <Setter Property="Padding" Value="2"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Background" Value="{StaticResource TabItem.Selected.Background}"/>
        <Setter Property="BorderBrush" Value="{StaticResource TabItem.Selected.Border}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabControl}">
                    <Grid x:Name="templateRoot" 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>
                        <!--容納標頭的東西-->
                        <StackPanel Grid.Column="0" Orientation="Horizontal" Margin="2,2,2,0" Grid.Row="0" Height="20" HorizontalAlignment="Left">
                            <StackPanel x:Name="headerPanel" Orientation="Horizontal" Background="Transparent" IsItemsHost="True"/>
                            <Button x:Name="AddItemButton" Content="+" Width="20"/>
                        </StackPanel>
                        <!--<TabPanel x:Name="headerPanel" Background="Transparent" 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="TextElement.Foreground" TargetName="templateRoot" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

然後寫對應的cs:
思路就是在OnApplyTemplate函數中通過VisualTreeHelper尋找對應的元素,然後進行事件綁定,這裏我綁定的是鼠標的移入事件

public class TabControlWithAddButton : TabControl
    {
        static TabControlWithAddButton()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(TabControlWithAddButton), new FrameworkPropertyMetadata(typeof(TabControlWithAddButton)));
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            var grid = VisualTreeHelper.GetChild(this, 0);
            var stackPanel = VisualTreeHelper.GetChild(grid, 0);
            var button = VisualTreeHelper.GetChild(stackPanel, 1) as Button;
            if(button != null)
            {
                button.MouseEnter += AddButtonMouseEntry;
            }
        }

        private void AddButtonMouseEntry(object sender, RoutedEventArgs e)
        {
            RoutedEventArgs routedEventArgs = new RoutedEventArgs(AddButtonEntryEvent, this);
            RaiseEvent(routedEventArgs);
        }

        public static RoutedEvent AddButtonEntryEvent = EventManager.RegisterRoutedEvent("AddButtonEntry", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TabControlWithAddButton));

        public event RoutedEventHandler AddButtonEntry
        {
            add
            {
                this.AddHandler(AddButtonEntryEvent, value);
            }

            remove
            {
                this.RemoveHandler(AddButtonEntryEvent, value);
            }
        }
    }

wpf給自定義控件定義事件
請教關於WPF上自定義控件添加事件的問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章