带有下拉箭头的DataGridComboBoxColumn

时间:2018-03-17 04:19:04

标签: wpf

我想在DatagridComboboxColumn中显示一个小向下箭头,表示这是一个下拉列表,如下图所示。

enter image description here

为了实现上述目的,我修改了ComboBoxToggleButton,方法是将路径更改为:

<Path x:Name="Arrow" Grid.Column="1" VerticalAlignment="Center" Data="M 0 0 L 6 6 L 12 0 Z">
    <Path.Fill>
        <SolidColorBrush Color="Gray" />
    </Path.Fill>
  </Path>

在ComboBox样式的弹出窗口中,我将其保留为默认值:

<Popup x:Name="Popup" AllowsTransparency="True" Focusable="False" IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" PopupAnimation="Slide">
   .....                                               
    <ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
         <StackPanel HorizontalAlignment="Left" IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
    </ScrollViewer>
   .....
</Popup>

我已将该样式命名为“ExpenseDescription”

最后,样式作为ElementStyle附加到DatagridComboBoxColumn,如下所示:

<DataGridComboBoxColum  ElementStyle="{StaticResource ExpenseDescription}
.......

这很好用。

但是我试图通过用Datagrid替换默认的StackPanel来修改ComboBox弹出窗口(下拉列表),以便下拉列表有多个列,如下所示(尽管在这个例子中我只显示了1列):

 <Popup x:Name="Popup" AllowsTransparency="True" Focusable="False" IsOpen="{TemplateBinding IsDropDownOpen}" Placement="Bottom" PopupAnimation="Slide">
 .....                                               
    <DataGrid AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{TemplateBinding ItemsSource}"  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
       <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Description}" Header="Account Description"/>
        </DataGrid.Columns>
    </DataGrid>
   .....
</Popup>

仅当我将样式附加到EditingElementStyle(而不是ElementStyle)并且上述箭头效果消失时才有效。

当我附加到ElementStyle时,我得到箭头效果,但所有行现在都绑定到相同的下拉选定项目,如下所示:

enter image description here

我试图通过插入

来修改样式
<Setter Property="IsSynchronizedWithCurrentItem" Value="False" />

效果是 SelectionChanged 事件不会触发。

在有人指示我另一个可能有用的例子之前,请帮我修改一下。

这是XAML

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="MainWindow"
        Width="300"
        Height="400">
    <Window.Resources>
        <local:DataSet1 x:Key="DataSet1" />
        <CollectionViewSource x:Key="ExpenseDetailsViewSource" Source="{Binding ExpenseDetails, Source={StaticResource DataSet1}}" />
        <CollectionViewSource x:Key="ExpenseDescriptionsViewSource" Source="{Binding ExpenseDescriptions, Source={StaticResource DataSet1}}" />
        <Style x:Key="Description" TargetType="{x:Type ComboBox}">
            <Setter Property="SnapsToDevicePixels" Value="true" />
            <Setter Property="OverridesDefaultStyle" Value="true" />
            <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
            <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
            <Setter Property="ScrollViewer.CanContentScroll" Value="true" />
            <Setter Property="Foreground" Value="Black" />
            <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ComboBox}">
                        <Grid>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal" />
                                    <VisualState x:Name="MouseOver" />
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ColorAnimationUsingKeyFrames Storyboard.TargetName="PART_EditableTextBox" Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
                                                <EasingColorKeyFrame KeyTime="0" Value="{DynamicResource DisabledForegroundColor}" />
                                            </ColorAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                                <VisualStateGroup x:Name="EditStates">
                                    <VisualState x:Name="Editable">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PART_EditableTextBox" Storyboard.TargetProperty="(UIElement.Visibility)">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentSite" Storyboard.TargetProperty="(UIElement.Visibility)">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Uneditable" />
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <ToggleButton x:Name="ToggleButton"
                                          Grid.Column="2"
                                          ClickMode="Press"
                                          Focusable="false"
                                          IsChecked="{Binding IsDropDownOpen,
                                                              Mode=TwoWay,
                                                              RelativeSource={RelativeSource TemplatedParent}}"
                                          Template="{DynamicResource ComboBoxToggleButton}" />
                            <ContentPresenter x:Name="ContentSite"
                                              Margin="3,3,23,3"
                                              HorizontalAlignment="Left"
                                              VerticalAlignment="Center"
                                              Content="{TemplateBinding SelectionBoxItem}"
                                              ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
                                              ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                                              IsHitTestVisible="False" />
                            <TextBox x:Name="PART_EditableTextBox"
                                     Margin="3,3,23,3"
                                     HorizontalAlignment="Left"
                                     VerticalAlignment="Bottom"
                                     Background="Transparent"
                                     Focusable="True"
                                     IsReadOnly="{TemplateBinding IsReadOnly}"
                                     Style="{x:Null}"
                                     TextAlignment="Left"
                                     Visibility="Hidden" />
                            <Popup x:Name="Popup"
                                   AllowsTransparency="True"
                                   Focusable="False"
                                   IsOpen="{TemplateBinding IsDropDownOpen}"
                                   Placement="Bottom"
                                   PopupAnimation="Slide">
                                <Grid x:Name="DropDown"
                                      MaxHeight="{TemplateBinding MaxDropDownHeight}"
                                      SnapsToDevicePixels="True">
                                    <Border x:Name="DropDownBorder" BorderThickness="0">

                                        <Border.BorderBrush>
                                            <SolidColorBrush Color="{DynamicResource ControlBackgroundColor}" />
                                        </Border.BorderBrush>
                                    </Border>
                                    <DataGrid AutoGenerateColumns="False"
                                              Background="Beige"
                                              CanUserAddRows="False"
                                              CanUserDeleteRows="False"
                                              ItemsSource="{TemplateBinding ItemsSource}"
                                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
                                        <DataGrid.Columns>
                                            <DataGridTextColumn MinWidth="150"
                                                                Binding="{Binding Description}"
                                                                Header="Account Description" />
                                        </DataGrid.Columns>
                                    </DataGrid>
                                </Grid>
                            </Popup>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="HasItems" Value="false">
                                <Setter TargetName="DropDownBorder" Property="MinHeight" Value="95" />
                            </Trigger>
                            <Trigger Property="IsGrouping" Value="true">
                                <Setter Property="ScrollViewer.CanContentScroll" Value="false" />
                            </Trigger>
                            <Trigger SourceName="Popup" Property="AllowsTransparency" Value="true">
                                <Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0" />
                                <Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0" />
                                <!--  <Setter TargetName="DropDownBorder" Property="CornerRadius"  Value="4" />  -->
                            </Trigger>
                            <Trigger SourceName="ToggleButton" Property="IsMouseOver" Value="true">
                                <Setter TargetName="ContentSite" Property="TextElement.Foreground" Value="Yellow" />
                                <Setter Property="Background" Value="{DynamicResource TabItemHotBackground}" />
                                <Setter Property="FontWeight" Value="Bold" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <EventSetter Event="SelectionChanged" Handler="SomeSelectionChanged" />
        </Style>
    </Window.Resources>
    <Grid x:Name="MainGrid" DataContext="{StaticResource ExpenseDetailsViewSource}">

        <DataGrid x:Name="ExpenseDetailsDataGrid"
                  AutoGenerateColumns="False"
                  EnableRowVirtualization="True"
                  ItemsSource="{Binding}"
                  RowDetailsVisibilityMode="VisibleWhenSelected">
            <DataGrid.Columns>
                <DataGridComboBoxColumn x:Name="MyDataGridComboBoxColumn"
                                        Width="*"
                                        DisplayMemberPath="Description"
                                        ElementStyle="{StaticResource Description}"
                                        Header="Expense Description"
                                        ItemsSource="{Binding Source={StaticResource ExpenseDescriptionsViewSource}}"
                                        SelectedValueBinding="{Binding Path=ExpenseDescription,
                                                                       FallbackValue=1,
                                                                       UpdateSourceTrigger=PropertyChanged}"
                                        SelectedValuePath="ControlNumber" />
            </DataGrid.Columns>

        </DataGrid>

    </Grid>
</Window>

这是后面的VB代码。 SomeSelectionChanged Sub只是为了强制DropDown列表关闭。

Imports System.Data
Imports System.IO
Imports System.IO.Packaging
Imports System.Runtime.InteropServices
Imports System.Threading
Imports Microsoft.Win32
Imports System.Data.OleDb
Imports System
Imports System.Windows
Imports System.Reflection
Imports System.Management
Imports System.ComponentModel
Imports System.Data.SqlClient
Imports System.Windows.Controls.Primitives


Imports System.Text

Imports System.Collections.Generic
Imports System.Linq



Class MainWindow

    Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles MyBase.Loaded

        Dim DataSet1 As WpfApplication1.DataSet1 = CType(Me.FindResource("DataSet1"), WpfApplication1.DataSet1)

        Dim dsNewRow As DataRow

        dsNewRow = DataSet1.Tables("ExpenseDescriptions").NewRow
        dsNewRow.Item("ControlNumber") = 1
        dsNewRow.Item("Description") = "Accounting Fees"
        DataSet1.Tables("ExpenseDescriptions").Rows.Add(dsNewRow)


        dsNewRow = DataSet1.Tables("ExpenseDescriptions").NewRow
        dsNewRow.Item("ControlNumber") = 2
        dsNewRow.Item("Description") = "Telephone"
        DataSet1.Tables("ExpenseDescriptions").Rows.Add(dsNewRow)

        dsNewRow = DataSet1.Tables("ExpenseDescriptions").NewRow
        dsNewRow.Item("ControlNumber") = 3
        dsNewRow.Item("Description") = "Insurance"
        DataSet1.Tables("ExpenseDescriptions").Rows.Add(dsNewRow)

        dsNewRow = DataSet1.Tables("ExpenseDescriptions").NewRow
        dsNewRow.Item("ControlNumber") = 4
        dsNewRow.Item("Description") = "Travel and Entertainment"
        DataSet1.Tables("ExpenseDescriptions").Rows.Add(dsNewRow)

        dsNewRow = DataSet1.Tables("ExpenseDescriptions").NewRow
        dsNewRow.Item("ControlNumber") = 5
        dsNewRow.Item("Description") = "Water and Lights"
        DataSet1.Tables("ExpenseDescriptions").Rows.Add(dsNewRow)


        dsNewRow = DataSet1.Tables("ExpenseDetails").NewRow
        dsNewRow.Item("ExpenseDescription") = 1
        DataSet1.Tables("ExpenseDetails").Rows.Add(dsNewRow)


        dsNewRow = DataSet1.Tables("ExpenseDetails").NewRow
        dsNewRow.Item("ExpenseDescription") = 2
        DataSet1.Tables("ExpenseDetails").Rows.Add(dsNewRow)

        dsNewRow = DataSet1.Tables("ExpenseDetails").NewRow
        dsNewRow.Item("ExpenseDescription") = 2
        DataSet1.Tables("ExpenseDetails").Rows.Add(dsNewRow)

        dsNewRow = DataSet1.Tables("ExpenseDetails").NewRow
        dsNewRow.Item("ExpenseDescription") = 3
        DataSet1.Tables("ExpenseDetails").Rows.Add(dsNewRow)

        dsNewRow = DataSet1.Tables("ExpenseDetails").NewRow
        dsNewRow.Item("ExpenseDescription") = 5
        DataSet1.Tables("ExpenseDetails").Rows.Add(dsNewRow)



    End Sub

    Private Sub SomeSelectionChanged(ByVal sender As Object, ByVal e As SelectionChangedEventArgs)

        Dim mycomboBox = CType(sender, ComboBox)
        mycomboBox.IsDropDownOpen = False

    End Sub


End Class

我明白你做了什么。我想使用DataGrid / ListView的原因是因为我想对数据进行排序和过滤。使用TextBlocks / TextBoxes,我将无法对下拉列表进行排序和调整。 如果需要,这里是C#代码。问题是,当我将样式放在 EditElementStyle 上时,它的工作正常。问题是当我尝试将样式设置为 ElementStyle 时。试试吧,你会明白我的意思

using System;
using System.Data;

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;


using System.Reflection;
using System.Management;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Windows.Controls.Primitives;



namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            WpfApplication1.DataSet1 dataSet1 = ((WpfApplication1.DataSet1)(this.FindResource("dataSet1")));

            DataRow dsNewRow = dataSet1.Tables["ExpenseDescriptions"].NewRow();
            dsNewRow["ControlNumber"] = 1;
            dsNewRow["Description"] = "Accounting Fees";
            dataSet1.Tables["ExpenseDescriptions"].Rows.Add(dsNewRow);

            dsNewRow = dataSet1.Tables["ExpenseDescriptions"].NewRow();
            dsNewRow["ControlNumber"] = 2;
            dsNewRow["Description"] = "Telephone";
            dataSet1.Tables["ExpenseDescriptions"].Rows.Add(dsNewRow);

            dsNewRow = dataSet1.Tables["ExpenseDescriptions"].NewRow();
            dsNewRow["ControlNumber"] = 3;
            dsNewRow["Description"] = "Insurance";
            dataSet1.Tables["ExpenseDescriptions"].Rows.Add(dsNewRow);

            dsNewRow = dataSet1.Tables["ExpenseDescriptions"].NewRow();
            dsNewRow["ControlNumber"] = 4;
            dsNewRow["Description"] = "Travel and Entertainment";
            dataSet1.Tables["ExpenseDescriptions"].Rows.Add(dsNewRow);

            dsNewRow = dataSet1.Tables["ExpenseDescriptions"].NewRow();
            dsNewRow["ControlNumber"] = 5;
            dsNewRow["Description"] = "Water and Lights";
            dataSet1.Tables["ExpenseDescriptions"].Rows.Add(dsNewRow);

            //================================

            dsNewRow = dataSet1.Tables["ExpenseDetails"].NewRow();
            dsNewRow["ExpenseDescription"] = 1;
            dataSet1.Tables["ExpenseDetails"].Rows.Add(dsNewRow);

            dsNewRow = dataSet1.Tables["ExpenseDetails"].NewRow();
            dsNewRow["ExpenseDescription"] = 2;
            dataSet1.Tables["ExpenseDetails"].Rows.Add(dsNewRow);

            dsNewRow = dataSet1.Tables["ExpenseDetails"].NewRow();
            dsNewRow["ExpenseDescription"] = 3;
            dataSet1.Tables["ExpenseDetails"].Rows.Add(dsNewRow);

            dsNewRow = dataSet1.Tables["ExpenseDetails"].NewRow();
            dsNewRow["ExpenseDescription"] = 4;
            dataSet1.Tables["ExpenseDetails"].Rows.Add(dsNewRow);

            dsNewRow = dataSet1.Tables["ExpenseDetails"].NewRow();
            dsNewRow["ExpenseDescription"] = 5;
            dataSet1.Tables["ExpenseDetails"].Rows.Add(dsNewRow);



        }

        private void SomeSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox mycomboBox = (ComboBox)sender;
            mycomboBox.IsDropDownOpen = false;

        }
    }
}

1 个答案:

答案 0 :(得分:0)

你写道:

  

这很好用。

然后请不要接受任何接受为ExpenseDescription设置这个风格ItemTemplate的定位器。因此,您将在ComboBox中获得多视图。

<Setter Property="ItemTemplate" >
    <Setter.Value>
        <DataTemplate>
            <Grid >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="70"/>
                    <ColumnDefinition Width="70"/>
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding ControlNumber}" Grid.Column="0"/>
                <TextBlock Text="{Binding Description}" Grid.Column="1"/>
            </Grid>
        </DataTemplate>
    </Setter.Value>
</Setter>