none
请问在WPF中如果实现如下控件 RRS feed

  • 问题

  • 请问如何实现一个Combobox(或者长的像他的控件),点击展开下拉菜单时显示三个控件,一个listbox,一个treeview,一个按钮。

    当单击按钮时显示和隐藏treeview控件。具体请看图

    下图时展开后

    2017年8月3日 12:17

答案

  • Hi,

    你可以尝试使用Popup控件来处理。

      <StackPanel>
    
            <Button x:Name="button" Height="20" Click="button_Click" Margin="10">
                <Button.Template>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <TextBox Background="AliceBlue"/>
                            <Path x:Name="triangle" FlowDirection="RightToLeft" Margin="0,5,5,0" Visibility="Visible" RenderTransformOrigin="1,0" Fill="Gray" Data="M 5,0 L5,0 10,10 L10,10 0,10 z">
    
                            </Path>
                        </Grid>
                    </ControlTemplate>
                </Button.Template>
            </Button>
            <Popup x:Name="buttonPopup"
                AllowsTransparency="True"
                IsOpen="False"
                Placement="Bottom"
                Width="{Binding ElementName=button, Path=ActualWidth}"
                PlacementTarget="{Binding ElementName=button}"
                PopupAnimation="Slide"
                StaysOpen="False">
                <StackPanel>
                    <ListBox>
                        <ListBox.ItemContainerStyle>
                            <Style TargetType="ListBoxItem">
                                <Style.Triggers>
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter Property="FontWeight" Value="Bold" />
                                        <Setter Property="Background" Value="Transparent" />
                                        <Setter Property="Foreground" Value="Red" />
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </ListBox.ItemContainerStyle>
                        <ListBoxItem HorizontalAlignment="Left">item1</ListBoxItem>
                        <ListBoxItem HorizontalAlignment="Left">item2item2</ListBoxItem>
                        <ListBoxItem HorizontalAlignment="Left">item3item3item3</ListBoxItem>
                        <ListBoxItem HorizontalAlignment="Left">item4item4item4item4item4</ListBoxItem>
                    </ListBox>
                    <Button x:Name="ExpandAll" Height="20" Click="ExpandAll_Click" Content="展开全部"/>
                    <Popup x:Name="ExpandAllPopup" 
                           AllowsTransparency="True" 
                           IsOpen="False" 
                           Placement="Bottom" 
                           Width="{Binding ElementName=ExpandAll, Path=ActualWidth}"
                           PlacementTarget="{Binding ElementName=ExpandAll}"
                           PopupAnimation="Slide"
                           StaysOpen="True">
                        <StackPanel>
                            <TreeView Height="300" KeyboardNavigation.TabNavigation="Cycle"  >
                                <TreeView.ItemContainerStyle>
                                    <Style TargetType="TreeViewItem">
                                        <Setter Property="KeyboardNavigation.TabNavigation" Value="Continue"/>
                                        <Setter Property="IsTabStop" Value="True"/>
                                    </Style>
                                </TreeView.ItemContainerStyle>
                                <TreeViewItem Header="Asia"   IsExpanded="True">
                                    <TreeViewItem Header="China"></TreeViewItem>
                                    <TreeViewItem Header="Japanese"></TreeViewItem>
                                    <TreeViewItem Header="Korea"></TreeViewItem>
                                </TreeViewItem>
                                <TreeViewItem Header="North America"   IsExpanded="True">
                                    <TreeViewItem Header="USA"></TreeViewItem>
                                    <TreeViewItem Header="Canada"></TreeViewItem>
                                    <TreeViewItem Header="Mexico"></TreeViewItem>
                                </TreeViewItem>
                                <TreeViewItem Header="South America" IsExpanded="True"  >
                                    <TreeViewItem Header="Argentina"></TreeViewItem>
                                    <TreeViewItem Header="Brazil"></TreeViewItem>
                                    <TreeViewItem Header="Uruguay"></TreeViewItem>
                                </TreeViewItem>
                            </TreeView>
                            <Button x:Name="collapseAll" Height="20" Click="collapseAll_Click" Content="收起" ></Button>
                        </StackPanel>
                    </Popup>
    
                </StackPanel>
            </Popup>
        </StackPanel>
      private void button_Click(object sender, RoutedEventArgs e)
            {
                buttonPopup.IsOpen = true;
            }
    
            private void ExpandAll_Click(object sender, RoutedEventArgs e)
            {
                ExpandAllPopup.IsOpen = true;
            }
    
            private void collapseAll_Click(object sender, RoutedEventArgs e)
            {
                ExpandAllPopup.IsOpen = false;
            }


    希望有帮助。

    Best Regards,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年8月4日 8:41
    版主
  • 感谢楼上的回答,我通过询问其他人也找到了类似的答案。

    代码如下

    <UserControl x:Class="下拉显示三个控件.CategoryComBobox"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:下拉显示三个控件"
                 xmlns:Converter="clr-namespace:下拉显示三个控件.Converter"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300" Loaded="UserControl_Loaded">
        <UserControl.Resources>
    
            <Converter:TreeViewLineConverter x:Key="LineConverter"/>
    
            <!--=================================================================
          TreeViewItem
      ==================================================================-->
    
            <Style  TargetType="{x:Type ListBoxItem}">
                <Setter Property="FontSize" Value="14"/>
                
                <Setter Property="SnapsToDevicePixels" Value="True"/>
                <Setter Property="Padding" Value="4,1"/>
                <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="1"/>
           
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="IsMouseOver" Value="True"/>
                                    </MultiTrigger.Conditions>
                                    <Setter Property="Foreground" Value="#3F91D7"/>
                                </MultiTrigger>
                                <Trigger Property="IsEnabled" Value="False">
                                    <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton">
                <Setter Property="Focusable" Value="False"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ToggleButton">
                      
                            <Grid Width="15" Height="13" SnapsToDevicePixels="True">
                                <!-- Rectangle 9x9 pixels -->
                                <Rectangle Width="9" Height="9" 
              Stroke="#919191" SnapsToDevicePixels="true">
                                    <Rectangle.Fill>
                                        <LinearGradientBrush EndPoint="0.5,2" StartPoint="0.5,0">
                                            <GradientStop Color="White" Offset="0"/>
                                            <GradientStop Color="Silver" Offset="0.5"/>
                                            <GradientStop Color="LightGray" Offset="1"/>
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                                <!-- Vertical line inside rectangle -->
                                <Rectangle x:Name="ExpandPath" Width="1" 
              Height="5" Stroke="Black" SnapsToDevicePixels="true"/>
                                <!-- Horizontal line inside rectangle -->
                                <Rectangle Width="5" Height="1" 
              Stroke="Black" SnapsToDevicePixels="true"/>
                            </Grid>
                          
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsChecked" Value="True">
                                    <Setter Property="Visibility"  
                TargetName="ExpandPath" Value="Collapsed"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="TreeViewItemFocusVisual">
                <Setter Property="Control.Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Border>
                                <Rectangle Margin="0,0,0,0"
                         StrokeThickness="5"
                         Stroke="Black"
                         StrokeDashArray="1 1"
                         Opacity="0"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
                <Setter Property="FontSize" Value="14"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="HorizontalContentAlignment"
              Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="VerticalContentAlignment"
              Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="Padding" Value="1,0,0,0"/>
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TreeViewItem}">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition MinWidth="19" Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
    
                                <!-- Connecting Lines -->
                                <Rectangle x:Name="HorLn" Height="1" Stroke="#8888"  Margin="9,0,0,0" SnapsToDevicePixels="true" StrokeDashArray="2" StrokeThickness="1"/>
                                <Rectangle x:Name="VerLn" Width="1" Stroke="#8888" Grid.RowSpan="2" SnapsToDevicePixels="true" StrokeDashArray="2" StrokeThickness="1"/>
                                <ToggleButton x:Name="Expander"
                          Style="{StaticResource ExpandCollapseToggleStyle}"
                          IsChecked="{Binding Path=IsExpanded,
                          RelativeSource={RelativeSource TemplatedParent}}"
                          ClickMode="Press"/>
                                <Border Name="Bd"
                      Grid.Column="1"
                      Background="{TemplateBinding Background}"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Padding="{TemplateBinding Padding}">
                                    <ContentPresenter x:Name="PART_Header"
                              ContentSource="Header"
                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                                </Border>
                                <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/>
                            </Grid>
                            <ControlTemplate.Triggers>
    
                                <!-- This trigger changes the connecting lines if the item is the last in the list -->
                                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource LineConverter}}" Value="true">
                                    <Setter TargetName="VerLn" Property="Height" Value="8"/>
                                    <Setter TargetName="VerLn" Property="VerticalAlignment" Value="Top"/>
                                </DataTrigger>
                                <Trigger Property="IsExpanded" Value="false">
                                    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
                                </Trigger>
                                <Trigger Property="HasItems" Value="false">
                                    <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
                                </Trigger>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="HasHeader" Value="false"/>
                                        <Condition Property="Width" Value="Auto"/>
                                    </MultiTrigger.Conditions>
                                    <Setter TargetName="PART_Header" Property="MinWidth" Value="75"/>
                                </MultiTrigger>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="HasHeader" Value="false"/>
                                        <Condition Property="Height" Value="Auto"/>
                                    </MultiTrigger.Conditions>
                                    <Setter TargetName="PART_Header" Property="MinHeight" Value="19"/>
                                </MultiTrigger>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Foreground" Value="#3F91D7"/>
                                </Trigger>
                               
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            
            <ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
                <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
            </ControlTemplate>
            <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="40" />
                    </Grid.ColumnDefinitions>
                    <Border Grid.Column="0" Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="#D6D8DE" Background="White"/>
    
                    <!--<Border Grid.Column="1" Background="#e8e8e8" Cursor="Hand"/>-->
                    <Path x:Name="Arrow" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z" Margin="16,16,10,10" Stretch="Fill" Fill="#cccccc" />
                </Grid>
            </ControlTemplate>
    
            <Style TargetType="{x:Type ComboBox}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ComboBox}">
                            <Grid>
                                <!-- ToggleButton 已数据绑定到 ComboBox 本身以切换 IsDropDownOpen -->
                                <ToggleButton Grid.Column="2" Template="{DynamicResource ComboBoxToggleButton}" 
                                              x:Name="ToggleButton" Focusable="false" 
                                              IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                                              ClickMode="Press"/>
                                <ContentPresenter HorizontalAlignment="Left" Margin="3,3,23,3" x:Name="ContentSite" 
                                                  VerticalAlignment="Center" Content="{Binding SelectedCategory.Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                                  ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
                                                  ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 
                                                  IsHitTestVisible="False"/>
                                <!--Content="{TemplateBinding SelectionBoxItem}"-->
    
                                <!-- 必须将 TextBox 命名为 PART_EditableTextBox,否则 ComboBox 将无法识别它 -->
                                <TextBox Visibility="Hidden" Template="{DynamicResource ComboBoxTextBox}" 
                                         HorizontalAlignment="Left" Margin="3,3,23,3" x:Name="PART_EditableTextBox" 
                                         Style="{x:Null}" VerticalAlignment="Center" Focusable="True" 
                                         Background="Transparent" IsReadOnly="{TemplateBinding IsReadOnly}"/>
    
                                <!-- Popup 可显示 ComboBox 中的项列表。IsOpen 已数据绑定到通过 ComboBoxToggleButton 来切换的 IsDropDownOpen -->
                                <Popup IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" x:Name="Popup" Focusable="False"
                                       AllowsTransparency="True" PopupAnimation="Slide">
                                    <Grid MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{TemplateBinding ActualWidth}" 
                                          x:Name="DropDown" SnapsToDevicePixels="True">
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <ListBox Background="#FBFBFB"  BorderBrush="#EFEFEF" BorderThickness="0 0 0 1" 
                                                 SelectionChanged="ListBox_SelectionChanged" 
                                                 ItemsSource="{Binding CommonCatetroyItem}" DisplayMemberPath="Name"/>
                                        <TreeView   x:Name="tree" Grid.Row="1" BorderThickness="0"  
                                                    Visibility="Collapsed"
                                                    TreeView.SelectedItemChanged="tb1_SelectedItemChanged"
                                                    ItemsSource="{Binding CatetroyItem}"/>
                                        <Button Content="展开全部" Click="Button_Click" x:Name="btnShow"
                                                Grid.Row="2" Background="#fbfbfb" BorderThickness="0 1 0 0" Foreground="#3F91D7" BorderBrush="#EFEFEF"/>
                                    </Grid>
                                </Popup>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </UserControl.Resources>
        <Grid>
            <ComboBox  x:Name="cmbMain" DropDownOpened="cmbMain_DropDownOpened" FontSize="14"/>
        </Grid>
    </UserControl>
    

    using System.Data;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using 下拉显示三个控件.Models;
    using 下拉显示三个控件.ViewModel;
    
    namespace 下拉显示三个控件
    {
        /// <summary>
        /// CategoryComBobox.xaml 的交互逻辑
        /// </summary>
        public partial class CategoryComBobox : UserControl
        {
            #region 变量
            /// <summary>
            /// 页面数据源
            /// </summary>
            PersonViewModel vm;
            #endregion
    
            #region 构造
            /// <summary>
            /// 构造
            /// </summary>
            public CategoryComBobox()
            {
                InitializeComponent();
            }
            #endregion
    
            #region 加载
            /// <summary>
            /// 加载
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                vm = DataContext as PersonViewModel;//显示数据源
            }
            #endregion
    
            #region 展开和收起材料树
            /// <summary>
            /// 展开和收起材料树
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Button btn = sender as Button;
                TreeView tree = cmbMain.Template.FindName("tree", cmbMain) as TreeView;
                if (tree.Visibility == Visibility.Collapsed)
                {
                    tree.Visibility = Visibility.Visible;
                    btn.Content = "收起";
                }
                else
                {
                    tree.Visibility = Visibility.Collapsed;
                    btn.Content = "展开全部";
                }
            }
            #endregion
    
            #region 选中材料树中的子节点
            /// <summary>
            /// 选中材料树中的子节点
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void tb1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
            {
                if (e.NewValue != null)
                {
                    TreeViewItem ti = e.NewValue as TreeViewItem;
                    if (ti != null)//在数据源中判断其是否有子节点,如果有,则不关闭,并且不显示内容
                    {
                        DataRow dr = ti.DataContext as DataRow;
                        if (dr != null)
                        {
                            var tempList = vm.AllCategory.FirstOrDefault(t => t.ParentCategoryCode == dr["CategoryCode"].ToString());// c.Select("ParentCategoryCode ='" + dr["CategoryCode"] + "'");
                            if (tempList != null)
                            {
                                return;
                            }
                            
                            vm.SelectedCategory.CategoryCode = dr["CategoryCode"].ToString();
                            vm.SelectedCategory.Name = dr["Name"].ToString();
                            vm.SelectedCategory.ParentCategoryCode = dr["ParentCategoryCode"].ToString();
                            cmbMain.IsDropDownOpen = false;
                        }
                    }
                }
            }
            #endregion
    
            #region 选中常用材料
            /// <summary>
            /// 选中常用材料
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (e.AddedItems != null && e.AddedItems.Count > 0)
                {
                    CategoryModel data = e.AddedItems[0] as CategoryModel;
                    vm.SelectedCategory.CategoryCode = data.CategoryCode;
                    vm.SelectedCategory.Name = data.Name;
                    vm.SelectedCategory.ParentCategoryCode = data.ParentCategoryCode;
                    cmbMain.IsDropDownOpen = false;
                }
            }
            #endregion
    
            #region 当常用数据为空时,直接显示树
            /// <summary>
            /// 当常用数据为空时,直接显示树
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void cmbMain_DropDownOpened(object sender, System.EventArgs e)
            {
                if (vm.CommonCatetroyItem == null || vm.CommonCatetroyItem.Count == 0)
                {
                    Button btn = cmbMain.Template.FindName("btnShow", cmbMain) as Button;
                    TreeView tree = cmbMain.Template.FindName("tree", cmbMain) as TreeView;
                    tree.Visibility = Visibility.Visible;
                    btn.Content = "收起";
                }
            } 
            #endregion
        }
    
    
    }
    

    using System;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    namespace 下拉显示三个控件.Converter
    {
        public class TreeViewLineConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                TreeViewItem item = (TreeViewItem)value;
                ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);
                return ic.ItemContainerGenerator.IndexFromContainer(item) == ic.Items.Count - 1;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }
    }
    


    • 已标记为答案 彭123 2017年8月5日 5:55
    • 已编辑 彭123 2017年8月5日 5:57
    2017年8月5日 5:55

全部回复

  • Hi,

    你可以尝试使用Popup控件来处理。

      <StackPanel>
    
            <Button x:Name="button" Height="20" Click="button_Click" Margin="10">
                <Button.Template>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Grid>
                            <TextBox Background="AliceBlue"/>
                            <Path x:Name="triangle" FlowDirection="RightToLeft" Margin="0,5,5,0" Visibility="Visible" RenderTransformOrigin="1,0" Fill="Gray" Data="M 5,0 L5,0 10,10 L10,10 0,10 z">
    
                            </Path>
                        </Grid>
                    </ControlTemplate>
                </Button.Template>
            </Button>
            <Popup x:Name="buttonPopup"
                AllowsTransparency="True"
                IsOpen="False"
                Placement="Bottom"
                Width="{Binding ElementName=button, Path=ActualWidth}"
                PlacementTarget="{Binding ElementName=button}"
                PopupAnimation="Slide"
                StaysOpen="False">
                <StackPanel>
                    <ListBox>
                        <ListBox.ItemContainerStyle>
                            <Style TargetType="ListBoxItem">
                                <Style.Triggers>
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter Property="FontWeight" Value="Bold" />
                                        <Setter Property="Background" Value="Transparent" />
                                        <Setter Property="Foreground" Value="Red" />
                                    </Trigger>
                                </Style.Triggers>
                            </Style>
                        </ListBox.ItemContainerStyle>
                        <ListBoxItem HorizontalAlignment="Left">item1</ListBoxItem>
                        <ListBoxItem HorizontalAlignment="Left">item2item2</ListBoxItem>
                        <ListBoxItem HorizontalAlignment="Left">item3item3item3</ListBoxItem>
                        <ListBoxItem HorizontalAlignment="Left">item4item4item4item4item4</ListBoxItem>
                    </ListBox>
                    <Button x:Name="ExpandAll" Height="20" Click="ExpandAll_Click" Content="展开全部"/>
                    <Popup x:Name="ExpandAllPopup" 
                           AllowsTransparency="True" 
                           IsOpen="False" 
                           Placement="Bottom" 
                           Width="{Binding ElementName=ExpandAll, Path=ActualWidth}"
                           PlacementTarget="{Binding ElementName=ExpandAll}"
                           PopupAnimation="Slide"
                           StaysOpen="True">
                        <StackPanel>
                            <TreeView Height="300" KeyboardNavigation.TabNavigation="Cycle"  >
                                <TreeView.ItemContainerStyle>
                                    <Style TargetType="TreeViewItem">
                                        <Setter Property="KeyboardNavigation.TabNavigation" Value="Continue"/>
                                        <Setter Property="IsTabStop" Value="True"/>
                                    </Style>
                                </TreeView.ItemContainerStyle>
                                <TreeViewItem Header="Asia"   IsExpanded="True">
                                    <TreeViewItem Header="China"></TreeViewItem>
                                    <TreeViewItem Header="Japanese"></TreeViewItem>
                                    <TreeViewItem Header="Korea"></TreeViewItem>
                                </TreeViewItem>
                                <TreeViewItem Header="North America"   IsExpanded="True">
                                    <TreeViewItem Header="USA"></TreeViewItem>
                                    <TreeViewItem Header="Canada"></TreeViewItem>
                                    <TreeViewItem Header="Mexico"></TreeViewItem>
                                </TreeViewItem>
                                <TreeViewItem Header="South America" IsExpanded="True"  >
                                    <TreeViewItem Header="Argentina"></TreeViewItem>
                                    <TreeViewItem Header="Brazil"></TreeViewItem>
                                    <TreeViewItem Header="Uruguay"></TreeViewItem>
                                </TreeViewItem>
                            </TreeView>
                            <Button x:Name="collapseAll" Height="20" Click="collapseAll_Click" Content="收起" ></Button>
                        </StackPanel>
                    </Popup>
    
                </StackPanel>
            </Popup>
        </StackPanel>
      private void button_Click(object sender, RoutedEventArgs e)
            {
                buttonPopup.IsOpen = true;
            }
    
            private void ExpandAll_Click(object sender, RoutedEventArgs e)
            {
                ExpandAllPopup.IsOpen = true;
            }
    
            private void collapseAll_Click(object sender, RoutedEventArgs e)
            {
                ExpandAllPopup.IsOpen = false;
            }


    希望有帮助。

    Best Regards,

    Bob


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2017年8月4日 8:41
    版主
  • 感谢楼上的回答,我通过询问其他人也找到了类似的答案。

    代码如下

    <UserControl x:Class="下拉显示三个控件.CategoryComBobox"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:下拉显示三个控件"
                 xmlns:Converter="clr-namespace:下拉显示三个控件.Converter"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300" Loaded="UserControl_Loaded">
        <UserControl.Resources>
    
            <Converter:TreeViewLineConverter x:Key="LineConverter"/>
    
            <!--=================================================================
          TreeViewItem
      ==================================================================-->
    
            <Style  TargetType="{x:Type ListBoxItem}">
                <Setter Property="FontSize" Value="14"/>
                
                <Setter Property="SnapsToDevicePixels" Value="True"/>
                <Setter Property="Padding" Value="4,1"/>
                <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="BorderBrush" Value="Transparent"/>
                <Setter Property="BorderThickness" Value="1"/>
           
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ListBoxItem}">
                            <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                                <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                            </Border>
                            <ControlTemplate.Triggers>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="IsMouseOver" Value="True"/>
                                    </MultiTrigger.Conditions>
                                    <Setter Property="Foreground" Value="#3F91D7"/>
                                </MultiTrigger>
                                <Trigger Property="IsEnabled" Value="False">
                                    <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="ExpandCollapseToggleStyle" TargetType="ToggleButton">
                <Setter Property="Focusable" Value="False"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ToggleButton">
                      
                            <Grid Width="15" Height="13" SnapsToDevicePixels="True">
                                <!-- Rectangle 9x9 pixels -->
                                <Rectangle Width="9" Height="9" 
              Stroke="#919191" SnapsToDevicePixels="true">
                                    <Rectangle.Fill>
                                        <LinearGradientBrush EndPoint="0.5,2" StartPoint="0.5,0">
                                            <GradientStop Color="White" Offset="0"/>
                                            <GradientStop Color="Silver" Offset="0.5"/>
                                            <GradientStop Color="LightGray" Offset="1"/>
                                        </LinearGradientBrush>
                                    </Rectangle.Fill>
                                </Rectangle>
                                <!-- Vertical line inside rectangle -->
                                <Rectangle x:Name="ExpandPath" Width="1" 
              Height="5" Stroke="Black" SnapsToDevicePixels="true"/>
                                <!-- Horizontal line inside rectangle -->
                                <Rectangle Width="5" Height="1" 
              Stroke="Black" SnapsToDevicePixels="true"/>
                            </Grid>
                          
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsChecked" Value="True">
                                    <Setter Property="Visibility"  
                TargetName="ExpandPath" Value="Collapsed"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="TreeViewItemFocusVisual">
                <Setter Property="Control.Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Border>
                                <Rectangle Margin="0,0,0,0"
                         StrokeThickness="5"
                         Stroke="Black"
                         StrokeDashArray="1 1"
                         Opacity="0"/>
                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            <Style x:Key="{x:Type TreeViewItem}" TargetType="{x:Type TreeViewItem}">
                <Setter Property="FontSize" Value="14"/>
                <Setter Property="Background" Value="Transparent"/>
                <Setter Property="HorizontalContentAlignment"
              Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="VerticalContentAlignment"
              Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
                <Setter Property="Padding" Value="1,0,0,0"/>
                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TreeViewItem}">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition MinWidth="19" Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto"/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>
    
                                <!-- Connecting Lines -->
                                <Rectangle x:Name="HorLn" Height="1" Stroke="#8888"  Margin="9,0,0,0" SnapsToDevicePixels="true" StrokeDashArray="2" StrokeThickness="1"/>
                                <Rectangle x:Name="VerLn" Width="1" Stroke="#8888" Grid.RowSpan="2" SnapsToDevicePixels="true" StrokeDashArray="2" StrokeThickness="1"/>
                                <ToggleButton x:Name="Expander"
                          Style="{StaticResource ExpandCollapseToggleStyle}"
                          IsChecked="{Binding Path=IsExpanded,
                          RelativeSource={RelativeSource TemplatedParent}}"
                          ClickMode="Press"/>
                                <Border Name="Bd"
                      Grid.Column="1"
                      Background="{TemplateBinding Background}"
                      BorderBrush="{TemplateBinding BorderBrush}"
                      BorderThickness="{TemplateBinding BorderThickness}"
                      Padding="{TemplateBinding Padding}">
                                    <ContentPresenter x:Name="PART_Header"
                              ContentSource="Header"
                              HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
                                </Border>
                                <ItemsPresenter x:Name="ItemsHost" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/>
                            </Grid>
                            <ControlTemplate.Triggers>
    
                                <!-- This trigger changes the connecting lines if the item is the last in the list -->
                                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource LineConverter}}" Value="true">
                                    <Setter TargetName="VerLn" Property="Height" Value="8"/>
                                    <Setter TargetName="VerLn" Property="VerticalAlignment" Value="Top"/>
                                </DataTrigger>
                                <Trigger Property="IsExpanded" Value="false">
                                    <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
                                </Trigger>
                                <Trigger Property="HasItems" Value="false">
                                    <Setter TargetName="Expander" Property="Visibility" Value="Hidden"/>
                                </Trigger>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="HasHeader" Value="false"/>
                                        <Condition Property="Width" Value="Auto"/>
                                    </MultiTrigger.Conditions>
                                    <Setter TargetName="PART_Header" Property="MinWidth" Value="75"/>
                                </MultiTrigger>
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="HasHeader" Value="false"/>
                                        <Condition Property="Height" Value="Auto"/>
                                    </MultiTrigger.Conditions>
                                    <Setter TargetName="PART_Header" Property="MinHeight" Value="19"/>
                                </MultiTrigger>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="Foreground" Value="#3F91D7"/>
                                </Trigger>
                               
                                <Trigger Property="IsEnabled" Value="false">
                                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
            
            <ControlTemplate x:Key="ComboBoxTextBox" TargetType="{x:Type TextBox}">
                <Border x:Name="PART_ContentHost" Focusable="False" Background="{TemplateBinding Background}" />
            </ControlTemplate>
            <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="40" />
                    </Grid.ColumnDefinitions>
                    <Border Grid.Column="0" Grid.ColumnSpan="2" BorderThickness="1" BorderBrush="#D6D8DE" Background="White"/>
    
                    <!--<Border Grid.Column="1" Background="#e8e8e8" Cursor="Hand"/>-->
                    <Path x:Name="Arrow" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z" Margin="16,16,10,10" Stretch="Fill" Fill="#cccccc" />
                </Grid>
            </ControlTemplate>
    
            <Style TargetType="{x:Type ComboBox}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type ComboBox}">
                            <Grid>
                                <!-- ToggleButton 已数据绑定到 ComboBox 本身以切换 IsDropDownOpen -->
                                <ToggleButton Grid.Column="2" Template="{DynamicResource ComboBoxToggleButton}" 
                                              x:Name="ToggleButton" Focusable="false" 
                                              IsChecked="{Binding Path=IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                                              ClickMode="Press"/>
                                <ContentPresenter HorizontalAlignment="Left" Margin="3,3,23,3" x:Name="ContentSite" 
                                                  VerticalAlignment="Center" Content="{Binding SelectedCategory.Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                                  ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" 
                                                  ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" 
                                                  IsHitTestVisible="False"/>
                                <!--Content="{TemplateBinding SelectionBoxItem}"-->
    
                                <!-- 必须将 TextBox 命名为 PART_EditableTextBox,否则 ComboBox 将无法识别它 -->
                                <TextBox Visibility="Hidden" Template="{DynamicResource ComboBoxTextBox}" 
                                         HorizontalAlignment="Left" Margin="3,3,23,3" x:Name="PART_EditableTextBox" 
                                         Style="{x:Null}" VerticalAlignment="Center" Focusable="True" 
                                         Background="Transparent" IsReadOnly="{TemplateBinding IsReadOnly}"/>
    
                                <!-- Popup 可显示 ComboBox 中的项列表。IsOpen 已数据绑定到通过 ComboBoxToggleButton 来切换的 IsDropDownOpen -->
                                <Popup IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" x:Name="Popup" Focusable="False"
                                       AllowsTransparency="True" PopupAnimation="Slide">
                                    <Grid MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{TemplateBinding ActualWidth}" 
                                          x:Name="DropDown" SnapsToDevicePixels="True">
                                        <Grid.RowDefinitions>
                                            <RowDefinition Height="Auto"/>
                                            <RowDefinition/>
                                            <RowDefinition Height="Auto"/>
                                        </Grid.RowDefinitions>
                                        <ListBox Background="#FBFBFB"  BorderBrush="#EFEFEF" BorderThickness="0 0 0 1" 
                                                 SelectionChanged="ListBox_SelectionChanged" 
                                                 ItemsSource="{Binding CommonCatetroyItem}" DisplayMemberPath="Name"/>
                                        <TreeView   x:Name="tree" Grid.Row="1" BorderThickness="0"  
                                                    Visibility="Collapsed"
                                                    TreeView.SelectedItemChanged="tb1_SelectedItemChanged"
                                                    ItemsSource="{Binding CatetroyItem}"/>
                                        <Button Content="展开全部" Click="Button_Click" x:Name="btnShow"
                                                Grid.Row="2" Background="#fbfbfb" BorderThickness="0 1 0 0" Foreground="#3F91D7" BorderBrush="#EFEFEF"/>
                                    </Grid>
                                </Popup>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </UserControl.Resources>
        <Grid>
            <ComboBox  x:Name="cmbMain" DropDownOpened="cmbMain_DropDownOpened" FontSize="14"/>
        </Grid>
    </UserControl>
    

    using System.Data;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls;
    using 下拉显示三个控件.Models;
    using 下拉显示三个控件.ViewModel;
    
    namespace 下拉显示三个控件
    {
        /// <summary>
        /// CategoryComBobox.xaml 的交互逻辑
        /// </summary>
        public partial class CategoryComBobox : UserControl
        {
            #region 变量
            /// <summary>
            /// 页面数据源
            /// </summary>
            PersonViewModel vm;
            #endregion
    
            #region 构造
            /// <summary>
            /// 构造
            /// </summary>
            public CategoryComBobox()
            {
                InitializeComponent();
            }
            #endregion
    
            #region 加载
            /// <summary>
            /// 加载
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                vm = DataContext as PersonViewModel;//显示数据源
            }
            #endregion
    
            #region 展开和收起材料树
            /// <summary>
            /// 展开和收起材料树
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Button btn = sender as Button;
                TreeView tree = cmbMain.Template.FindName("tree", cmbMain) as TreeView;
                if (tree.Visibility == Visibility.Collapsed)
                {
                    tree.Visibility = Visibility.Visible;
                    btn.Content = "收起";
                }
                else
                {
                    tree.Visibility = Visibility.Collapsed;
                    btn.Content = "展开全部";
                }
            }
            #endregion
    
            #region 选中材料树中的子节点
            /// <summary>
            /// 选中材料树中的子节点
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void tb1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
            {
                if (e.NewValue != null)
                {
                    TreeViewItem ti = e.NewValue as TreeViewItem;
                    if (ti != null)//在数据源中判断其是否有子节点,如果有,则不关闭,并且不显示内容
                    {
                        DataRow dr = ti.DataContext as DataRow;
                        if (dr != null)
                        {
                            var tempList = vm.AllCategory.FirstOrDefault(t => t.ParentCategoryCode == dr["CategoryCode"].ToString());// c.Select("ParentCategoryCode ='" + dr["CategoryCode"] + "'");
                            if (tempList != null)
                            {
                                return;
                            }
                            
                            vm.SelectedCategory.CategoryCode = dr["CategoryCode"].ToString();
                            vm.SelectedCategory.Name = dr["Name"].ToString();
                            vm.SelectedCategory.ParentCategoryCode = dr["ParentCategoryCode"].ToString();
                            cmbMain.IsDropDownOpen = false;
                        }
                    }
                }
            }
            #endregion
    
            #region 选中常用材料
            /// <summary>
            /// 选中常用材料
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
                if (e.AddedItems != null && e.AddedItems.Count > 0)
                {
                    CategoryModel data = e.AddedItems[0] as CategoryModel;
                    vm.SelectedCategory.CategoryCode = data.CategoryCode;
                    vm.SelectedCategory.Name = data.Name;
                    vm.SelectedCategory.ParentCategoryCode = data.ParentCategoryCode;
                    cmbMain.IsDropDownOpen = false;
                }
            }
            #endregion
    
            #region 当常用数据为空时,直接显示树
            /// <summary>
            /// 当常用数据为空时,直接显示树
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void cmbMain_DropDownOpened(object sender, System.EventArgs e)
            {
                if (vm.CommonCatetroyItem == null || vm.CommonCatetroyItem.Count == 0)
                {
                    Button btn = cmbMain.Template.FindName("btnShow", cmbMain) as Button;
                    TreeView tree = cmbMain.Template.FindName("tree", cmbMain) as TreeView;
                    tree.Visibility = Visibility.Visible;
                    btn.Content = "收起";
                }
            } 
            #endregion
        }
    
    
    }
    

    using System;
    using System.Windows.Controls;
    using System.Windows.Data;
    
    namespace 下拉显示三个控件.Converter
    {
        public class TreeViewLineConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                TreeViewItem item = (TreeViewItem)value;
                ItemsControl ic = ItemsControl.ItemsControlFromItemContainer(item);
                return ic.ItemContainerGenerator.IndexFromContainer(item) == ic.Items.Count - 1;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }
    }
    


    • 已标记为答案 彭123 2017年8月5日 5:55
    • 已编辑 彭123 2017年8月5日 5:57
    2017年8月5日 5:55