4

Entity Framework、CRUD操作、およびMVVMを使用して、ユーザーが従業員に関する詳細を入力できるWPFアプリケーションを作成しています。

これまでのところ、私は 2 つ持っていListViewsます。1 つには従業員名のリスト (listview1) が含まれ、もう 1 つ (listview2) には生年月日や住所などの詳細がリストされています。

リストビュー

CollectionViewSorucelistbox1 から特定の名前を選択したときに、listview2 で結果をフィルタリングできるようにするためにを使用しています。これまでのところ、これを達成することはできますが、従業員を追加または削除すると、例外がスローされます。

 An unhandled exception of type 'System.StackOverflowException' occurred in *.UI.exe

ここに役立つかもしれないコードスニペットがあります

ビューモデル:

    private EmployeeListViewModel()
        : base("")
    {
        EmployeeList = new ObservableCollection<EmployeeViewModel>(GetEmployees());
        this._employeeCol = new ListCollectionView(this.employeeList); 
    }

    private ListCollectionView _employeeCol;
    public ICollectionView EmployeeCollection
    {
        get { return this._employeeCol; }
    }

    private ObservableCollection<EmployeeViewModel> employeeList;
    public ObservableCollection<EmployeeViewModel> EmployeeList
    {
        get { return employeeList; }
        set
        {
            employeeList = value;
            OnPropertyChanged("EmployeeList");
        }
    }

    private EmployeeViewModel selectedEmployee = null;
    public EmployeeViewModel SelectedEmployee
    {
        get
        {
            return selectedEmployee;
        }
        set
        {
            selectedEmployee = value;
            OnPropertyChanged("SelectedEmployee");
            EmployeeCollection.Filter = new Predicate<object>(o => SelectedEmployee != null && o != null && ((EmployeeViewModel)o).EmployeeID == SelectedEmployee.EmployeeID);
        }
    }

    internal ObservableCollection<EmployeeViewModel> GetEmployees()
    {
        if (employeeList == null)
            employeeList = new ObservableCollection<EmployeeViewModel>();
        employeeList.Clear();

        foreach (DataObjects.Employee i in new EmployeeRepository().GetAllEmployees())
        {
            EmployeeViewModel c = new EmployeeViewModel(i);
            employeeList.Add(c);
        }
        return employeeList;
    }

ListView2 - EmployeeListView;

            <ListView Name="lsvEmpoyeeList" Height="170" Width="700"
                  ScrollViewer.VerticalScrollBarVisibility="Visible" 
                  ScrollViewer.HorizontalScrollBarVisibility="Visible" 
                  HorizontalAlignment="Center"
                  IsSynchronizedWithCurrentItem="True"
                  ItemsSource="{Binding EmployeeCollection}"
                  SelectedItem="{Binding SelectedEmployee}">
                    <ListView.View>
                      <GridView>
                        <GridViewColumn Header="Position" DisplayMemberBinding="{Binding Position}" Width="100" />
                        <GridViewColumn Header="DateOfBirth" DisplayMemberBinding="{Binding DateOfBirth, StringFormat={}\{0:dd/MM/yyyy\}}" Width="100" />
                     </GridView>
                    </ListView.View>
                </ListView>

ListView1 - EmployeeSetUpView;

            <ListView Height="380" HorizontalAlignment="Left" Name="lsNames" VerticalAlignment="Top" Width="170" 
             ScrollViewer.VerticalScrollBarVisibility="Visible" 
             ScrollViewer.HorizontalScrollBarVisibility="Visible" 
             SelectedItem="{Binding SelectedEmployee}" 
             ItemsSource="{Binding EmployeeList}" Grid.RowSpan="2" Grid.Row="1">

        <ListView.View>
            <GridView>
                <GridViewColumn Header="FirstName" DisplayMemberBinding="{Binding FirstName}" Width="80" />
                <GridViewColumn Header="Surname" DisplayMemberBinding="{Binding Surname}" Width="80" />
            </GridView>
        </ListView.View>
    </ListView>
   <ContentControl Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center"
                    Content="{Binding}" ContentTemplate="{StaticResource EmployeeListView}" />

ご覧のとおり、フィルターを 内に配置しましたsetaccessor。コンストラクター内に配置しましたが、ListView2 に詳細が表示されなかったようです。

さらに、listview1 ではなく listview2 から行を選択すると、StackOverFlowException理由がわからない も生成されます。

任意のヘルプまたはアドバイスをいただければ幸いです。また、大きな質問で申し訳ありません!

4

1 に答える 1

3

UIEmployeeCollectionが変更されたことを認識していないと思います

フィルターが適用された後、setter にイベントPropertyChangedを追加してみてください。EmployeeCollectionSelectedEmployee

public EmployeeViewModel SelectedEmployee
{
    get { return selectedEmployee;}
    set
    {
        selectedEmployee = value;
        OnPropertyChanged("SelectedEmployee");
        EmployeeCollection.Filter = new Predicate<object>(o => SelectedEmployee != null && o != null && ((EmployeeViewModel)o).EmployeeID == SelectedEmployee.EmployeeID);

        // EmployeeCollection view has changed, Notify UI
        OnPropertyChanged("EmployeeCollection");
    }
}

そして、これは両方がon にバインドされStackOverflowExceptionていることが原因だと思います。そのため、1 つの ListView1 が SelectedItem を変更すると、ListView2 が選択された項目を更新し、ListView1 などを更新します。ListViewTwoWaySelectedEmployee

SelectedEmployeeListView2でバインディングを OneWay に設定してみてください

SelectedItem="{Binding SelectedEmployee, Mode=OneWay}">

于 2013-03-11T10:21:01.870 に答える