0

2つのコンボボックス列を持つデータグリッドがあります。最初のコンボボックスは、PersonnelTypesのリストです。選択したPersonnelTypeに応じて、2番目のコンボボックスには、選択したPersonnelTypeに一致するリソースのリストが表示されます。

問題は、2行のデータがあるとしましょう。1行のPersonnelTypeを変更すると、datagridはすべての行のすべてのリソースのitemsourceを設定します。すべての行ではなく、自分がいる行のみをフィルタリングする必要があります。

コンボボックスがあるデータグリッドの部分のxamlは次のとおりです。

                    <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は次のとおりです(表示する必要がある場合に備えて)。

            <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)の背後にあるコードは次のとおりです。

    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のコードは次のとおりです。

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());
}

もっと見る必要がある場合は、私に知らせてください

4

2 に答える 2

1

さて、ここで働いている同僚の助けを借りて、私たちは何をする必要があるかを理解しました。マルチバインディングがその答えです。まず、2つのコンボボックスを両方ともグリッドに配置し、グリッドを1つの列に配置することで、2つのコンボボックスを同じ列に配置できるようにハッキングしました。これで、両方のコンボボックスが同じDataGridTemplateColumnにあるため、お互いを見ることができます。以前は、2つの別々のDataGridTemplateColumnsであるためにお互いのスコープを失ったため、お互いを見ることができませんでした。

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>

FilteredPersonnelConverterと呼ばれるMultiBindingにValueConverterがあることに気付くでしょう。この値コンバーターは、私のためにすべてのフィルタリングを行います。そのためのコードは次のとおりです。

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();
    }
}

だから誰か他の人がこのようなことをしているなら、マルチバインディングを調べてください、それはあなたの人生を変えるでしょう

于 2013-02-08T15:55:18.320 に答える
0

ユーザーがビューのPersonelTypeドロップダウンを変更すると、ViewModelはリソースのリストをフィルタリングする必要があります(これにより、2番目のドロップダウンボックスが正しい情報で更新されます)。

実際には、ビューの変更に対応するようにビューモデルを設定する必要があります。それが要約されます。

ここを見て:

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());

}

コンストラクターで個人タイプを設定したように見えますが、ユーザーの変更に応答していません。ビューモデルのPersonelTypeバインディングでこれを行う必要があります。

編集

変更された選択を処理していることがわかります。しかし、実際には、これはビューモデル自体で行う必要があると思います。具体的には、ビューから実際にビューモデルにアクセスして変更を加えるためです。

これが私のVMです:

class ViewModel : INotifyPropertyChanged
{
    DispatcherTimer timer = new DispatcherTimer();

    public ViewModel()
    {
        // Create my observable collection
        this.DateTimes = new ObservableCollection<DateTime>();

        // Every second add anothe ritem
        timer.Interval = TimeSpan.FromSeconds(1);
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();
    }

    void timer_Tick(object sender, EventArgs e)
    {
        // This adds to the collection
        this.DateTimes.Add(DateTime.Now);
    }

    public ObservableCollection<DateTime> DateTimes { get; private set; }

    public event PropertyChangedEventHandler PropertyChanged;
}

と私の見解:

<ListBox ItemsSource="{Binding DateTimes}"/> 

コレクションを再構築しないことに注意してください。一度設定して、必要に応じてサイズを変更します。

于 2013-02-07T17:31:29.023 に答える