一个组合框过滤WPF Datagrid中的另一个组合框 [英] One combo box filtering another combo box in a WPF Datagrid

查看:148
本文介绍了一个组合框过滤WPF Datagrid中的另一个组合框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个datagrid它有两个组合框列。第一个组合框是PersonnelTypes的列表。根据选择的PersonnelType,第二个组合框应该填充与所选PersonnelType匹配的资源列表

I have a datagrid which has two combo box columns in it. The first combo box is a list of PersonnelTypes. Depending on which PersonnelType is selected, the second combo box should fill up with a list of Resources that match the selected PersonnelType

问题是,我有两行数据,如果我更改一行的PersonnelType,datagrid将为每一行中的所有资源设置itemsource。我只想让它过滤我的行,而不是所有的行。

The problem is, lets say I have two rows of data, if I change the PersonnelType of one row, the datagrid will set the itemsource for all of the Resources in every row. I only want it to filter the row that I am in, not all the rows.

这里是xaml的datagrid有组合框的部分:

Here's the xaml for the part of the datagrid that has the combo boxes:

                    <DataGridTemplateColumn  Header="Personnel Type" Width="Auto">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Grid>
                                    <ComboBox Name="cmbPersonnelTypes" FontWeight="Bold" ItemsSource="{Binding ViewModel.PersonnelTypes, RelativeSource={RelativeSource AncestorType=Window}}"  SelectedItem="{Binding PersonnelType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="ID" DisplayMemberPath="Description" SelectionChanged="cmbPersonnelTypes_SelectionChanged" />
                                </Grid>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn  Header="Name" Width="Auto">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Grid>
                                    <ComboBox Name="cmbPersonnelName" FontWeight="Bold" ItemsSource="{Binding ViewModel.ResourcesToChooseFrom, RelativeSource={RelativeSource AncestorType=Window},UpdateSourceTrigger=PropertyChanged}"   SelectedItem="{Binding Resource, Mode=TwoWay}" SelectedValuePath="Refno" DisplayMemberPath="Name" />
                                </Grid>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn> 

这里是整个数据网格的xaml(只是为了你需要看到它) / p>

Here is the xaml for the whole data grid (just in case you need to see it):

            <DataGrid AutoGenerateColumns="False" CanUserSortColumns="False" CanUserDeleteRows="True" IsReadOnly="True" Background="LightGray" CanUserAddRows="False" Margin="5" SelectedItem="{Binding SelectedLA_JobPersonnel}" ItemsSource="{Binding LA_Personnel}" Grid.ColumnSpan="4" MouseDoubleClick="DataGrid_MouseDoubleClick_1">
                <DataGrid.Resources>
                    <ViewModels:BindingProxy x:Key="proxy" Data="{Binding}" />
                </DataGrid.Resources>
                <DataGrid.Columns>
                    <DataGridTemplateColumn  Header="Personnel Type" Width="Auto">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Grid>
                                    <ComboBox Name="cmbPersonnelTypes" FontWeight="Bold" ItemsSource="{Binding ViewModel.PersonnelTypes, RelativeSource={RelativeSource AncestorType=Window}}"  SelectedItem="{Binding PersonnelType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="ID" DisplayMemberPath="Description" SelectionChanged="cmbPersonnelTypes_SelectionChanged" />
                                </Grid>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn  Header="Name" Width="Auto">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Grid>
                                    <ComboBox Name="cmbPersonnelName" FontWeight="Bold" ItemsSource="{Binding ViewModel.ResourcesToChooseFrom, RelativeSource={RelativeSource AncestorType=Window},UpdateSourceTrigger=PropertyChanged}"   SelectedItem="{Binding Resource, Mode=TwoWay}" SelectedValuePath="Refno" DisplayMemberPath="Name" />
                                </Grid>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>                            <DataGridTemplateColumn Header="Date Out"  Width="20*" >

                        <DataGridTemplateColumn.CellTemplate>

                            <DataTemplate>

                                <TextBlock Background="LightGray" FontWeight="Bold" Text="{Binding DateOut, Mode=TwoWay, Converter={StaticResource thisNullDateConverter}, StringFormat={}{0:MMM-dd-yyyy hh:ss tt}}">
                                </TextBlock>
                            </DataTemplate>

                        </DataGridTemplateColumn.CellTemplate>

                        <DataGridTemplateColumn.CellEditingTemplate>

                            <DataTemplate>
                                <Toolkit:DateTimePicker Background="LightGray" FontWeight="Bold" Value="{Binding Path=DateOut, Mode=TwoWay, Converter={StaticResource thisNullDateConverter}}" Format="Custom" FormatString="MMM dd yyyy hh:ss tt"></Toolkit:DateTimePicker>

                            </DataTemplate>

                        </DataGridTemplateColumn.CellEditingTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn Header="Date In"  Width="20*">

                        <DataGridTemplateColumn.CellTemplate>

                            <DataTemplate>

                                <TextBlock Background="LightGray" FontWeight="Bold" Text="{Binding DateIn, Mode=TwoWay, Converter={StaticResource thisNullDateConverter}, StringFormat={}{0:MMM-dd-yyyy hh:ss tt}}">
                                </TextBlock>
                            </DataTemplate>

                        </DataGridTemplateColumn.CellTemplate>

                        <DataGridTemplateColumn.CellEditingTemplate>

                            <DataTemplate>
                                <Toolkit:DateTimePicker Background="LightGray" FontWeight="Bold" Value="{Binding Path=DateIn, Mode=TwoWay, Converter={StaticResource thisNullDateConverter}}" Format="Custom" FormatString="MMM dd yyyy hh:ss tt"></Toolkit:DateTimePicker>

                            </DataTemplate>

                        </DataGridTemplateColumn.CellEditingTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>


            </DataGrid>

以下是xaml(xaml.cs)的代码:

Here is the code behind for the xaml (xaml.cs):

    public JobEditorViewModel ViewModel
    {
        get { return viewModel; }
    }

private void cmbPersonnelTypes_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var combobox = sender as ComboBox;
        if (combobox != null)
        {
            var selectedPersonnelType = combobox.SelectedItem as PersonnelType;
            viewModel.SetResourcesToChooseFrom(selectedPersonnelType);
        }
    }

这是viewModel中的代码:

Here is the code in the viewModel:

public BindingList<PersonnelType> PersonnelTypes
{
    get; set;
}
public JobEditorViewModel(int jobid, string region, DataAccessDataContext db, ServiceUserControlViewModel serviceViewModel)
{

    PersonnelTypes = new BindingList<PersonnelType>(_db.PersonnelTypes.OrderBy(p => p.Head).ThenBy(p => p.Description).ToList());

}


private BindingList<Resource> _resourcesToChooseFrom;


public BindingList<Resource> ResourcesToChooseFrom
{
    get { return _resourcesToChooseFrom; }
    set
    {
        _resourcesToChooseFrom = value;
        NotifyPropertyChanged("ResourcesToChooseFrom");
    }
}

public void SetResourcesToChooseFrom(PersonnelType personnelType)
{
   ResourcesToChooseFrom =
        new BindingList<Resource>(_db.Resources.Where(r => r.Head == personnelType.Head && r.Refno > 2).OrderBy(r=>r.Name).ToList());
}

如果您需要查看更多,请告诉我

If you need to see more, let me know

推荐答案

很好,在工作的同事的帮助下,我们想出了我需要做的。多绑定是答案。首先,我们被黑客攻击,以便两个组合框可以在同一列中,将它们放在一个网格中,并将网格放在一列。所以现在两个组合框可以看到对方,因为他们在同一个DataGridTemplateColumn。之前,我们不能让他们看到对方,因为他们在两个单独的DataGridTemplateColumns中失去了彼此的范围。

Well, with some help from a colleague here at work, we figured out what I needed to do. Multibinding is the answer. First off we kind of hacked around so that the two combo boxes could be in the same column by placing them both in a grid and placing the grid in the one column. So now both combo boxes can see each other because they are in the same DataGridTemplateColumn. Before, we couldn't get them to see each other because they lost scope of each other in being two separate DataGridTemplateColumns.

这里是我们在xaml:

Here's what we did in the xaml:

                                <DataGridTemplateColumn  Header="Personnel Type-Name" Width="Auto" >
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                            <Grid >
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="170"/>
                                                    <ColumnDefinition Width="*"/>
                                                </Grid.ColumnDefinitions>

                                                <Border Grid.Column="0" BorderBrush="Black" BorderThickness="1">
                                                    <TextBlock Text="{Binding PersonnelType.Description}"/>
                                                </Border>
                                                <Border Grid.Column="1" BorderBrush="Black" BorderThickness="1">
                                                    <TextBlock  Text="{Binding Resource.Name}"/>
                                                </Border>

                                            </Grid>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>


                                    <DataGridTemplateColumn.CellEditingTemplate>
                                        <DataTemplate>
                                            <Grid >
                                                <Grid.ColumnDefinitions>
                                                    <ColumnDefinition Width="170"/>
                                                    <ColumnDefinition Width="*"/>
                                                </Grid.ColumnDefinitions>


                                                <ComboBox Name="cmbPersonnelTypes" Grid.Column="0" FontWeight="Bold" ItemsSource="{Binding ViewModel.PersonnelTypes, RelativeSource={RelativeSource AncestorType=Window}, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding PersonnelType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="ID" DisplayMemberPath="Description" />
                                                <ComboBox Name="cmbPersonnelName" Grid.Column="1"  FontWeight="Bold" SelectedItem="{Binding Resource, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Refno" DisplayMemberPath="Name" >
                                                    <ComboBox.ItemsSource>
                                                        <MultiBinding Converter="{StaticResource FilteredPersonnelConverter}">
                                                            <Binding Path="ViewModel.AvailablePersonnel" RelativeSource="{RelativeSource AncestorType=Window}"/>
                                                            <Binding Path="SelectedItem" ElementName="cmbPersonnelTypes"/>
                                                            <Binding Path="ViewModel.SelectedGlobalResourceViewOption" RelativeSource="{RelativeSource AncestorType=Window}"/>
                                                        </MultiBinding>
                                                    </ComboBox.ItemsSource>
                                                </ComboBox>

                                            </Grid>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellEditingTemplate>

                                </DataGridTemplateColumn>

你会注意到MultiBinding中有一个名为FilteredPersonnelConverter的ValueConverter。这个值转换器为我做所有的过滤。下面是代码:

You'll notice there is a ValueConverter in the MultiBinding called FilteredPersonnelConverter. This value converter does all the filtering for me. Here's the code for that:

public class FilteredPersonnelListValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        var allResources = values[0] as IList<Resource>;
        var personnelType = values[1] as PersonnelType;
        var selectedGlobalResourceView = values[2] as ResourceViewOption;
        if (personnelType == null)
            return allResources;
        if(selectedGlobalResourceView.ResourceViewTitle=="Regional")
            return allResources.Where(r => r.Head == personnelType.Head && r.Obsolete == false && r.Location.Region.RegionID.Trim()==SettingsManager.OpsMgrSettings.Region.Trim()).OrderBy(r => r.Name).ToList();
        if (selectedGlobalResourceView.ResourceViewTitle == "Local")
            return allResources.Where(r => r.Head == personnelType.Head && r.Obsolete == false && r.LocnID.Trim() == SettingsManager.OpsMgrSettings.LOCNCODE.Trim()).OrderBy(r => r.Name).ToList();

        return allResources.Where(r => r.Head == personnelType.Head &&r.Obsolete==false).OrderBy(r => r.Name).ToList();

    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

因此,如果任何人正在做这样的事情, into Multibinding,它会改变你的生活

So if anyone else is doing something like this, look into Multibinding, it will change your life

这篇关于一个组合框过滤WPF Datagrid中的另一个组合框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆