首页 > 解决方案 > 如何绑定来自同一个 ICollectionView 的不同 UserControl 中的对象的子属性?

问题描述

我正在使用 MVVM 并希望将 Car.Name 绑定到 aListBox并绑定CarDetailsListListViewusing GridView。任何帮助是极大的赞赏。

有一个Model

public class Car : ObservableObject  // ObservableObject simply means that this object is subject to PropertyChanged notifications.
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { OnPropertyChanged(ref _name, value); }
        }     

        private List<CarDetail> _carDetailsList;
        public List<CarDetail> CarDetailsList
        {
            get { return _carDetailsList; }
            set { OnPropertyChanged(ref _carDetailsList, value); }
        }

        // CarDetail makes up a list of properties for the object Car for each "Name"
        public class CarDetail: ObservableObject
        {
            private string _engineType;
            public string EngineType
            {
                get { return _engineType; }
                set { OnPropertyChanged(ref _engineType, value); }
            }

            private string _color;
            public string Color
            {
                get { return _color; }
                set { OnPropertyChanged(ref _color, value); }
            }           
        }
    }

ViewModel包含以下内容:

一个ObservableCollectionCars

public ObservableCollection<Car> Cars { get; set; }

ICommands

public ICommand SaveCarNameCommand { get; private set; }
public ICommand SaveCarDetailCommand { get; private set; }

一个ICollectionView

 private ICollectionView _carView;
        public ICollectionView CarView
        {
            get { return _carView; }
            set { OnPropertyChanged(ref _carView, value); }
        } 

两个属性:

private Car _selectedCar;
    public Car SelectedCar
    {
        get { return _selectedCar; }
        set
        {
            OnPropertyChanged(ref _selectedCar, value);
        }
    }
       private Car _selectedCarDetail;
    public Car SelectedCarDetial
    {
        get { return _selectedCarDetail; }
        set
        {
            OnPropertyChanged(ref _selectedCarDetail, value);
        }
    }
    

承包商:

public CarsForSaleViewModel()
{
    Cars = new ObservableCollection<Car>();
    CarView = (CollectionView)new CollectionViewSource { Source = Cars }.View;
    OnPropertyChanged("CarView");
    SaveCarCommand = new RelayCommand(SaveCar);
    SaveCarDetailCommand = new RelayCommand(SaveCarDetail);
    SelectedCar = Cars[0]; //Selects the first Car        
}

ICommand行动:

private void SaveCarDetail()
        {
            var newCarDetail = new Car.CarDetail
            {
                EngineType = SelectedCarDetial.EngineType,
                Color = SelectedCarDetial.Color               
            };
            // Add newCarDetail to CarDetailsList of "SelectedCar" in "DetailsList"
            SelectedCar.CarDetailsList.Add(newCarDetail); 
            CarView.Refresh();
            SelectedCarDetial = newCarDetail; // Selects the newly added item in the list
        }
        
        private void CarSave()
        {
            var newCar = new Car
            {
                Name = SelectedCar.Name,
                CarDetailsList = new List<Car.CarDetail>()
            };
          
            Cars.Add(newCar); // Add newCar to "CarList"
            CarView.Refresh();
            SelectedCar = newCar; // Selects the newly added item in the list
        }
    

我有一个View名为“CarsForSaleView”的三 (3) 个UserControls

第一个UserControl“CarView”显示所有Cars按名称。

<ListBox IsSynchronizedWithCurrentItem="True" 
ItemsSource="{Binding CarView}" 
SelectedItem="{Binding SelectedCar, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                

第二个Usercontrol“DetailsView”显示SelectedCar“CarsList”中的详细信息。

<ListView IsSynchronizedWithCurrentItem="True"
          ItemsSource="{Binding SelcetedCar.CarDetailsList}" 
          SelectedItem="{Binding SelectedCarDetial}">
    <ListView.View>
        <GridView AllowsColumnReorder="False">
            <GridViewColumn Header="Engine Type">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding EngineType}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Color">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Color}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

第三个UserControl“SaveCarView”允许用户在绑定到属性Name的 a 中输入 a。当我单击保存时,“CarsList”会更新为带有用户输入名称的新项目。效果很好!TextBoxName

第四UserControl个“SaveCarDetailView”允许用户通过组合框选择EngineTypeColorSelectedCar每个组合框都绑定到各自的CarDetail属性。当我单击保存时,该项目被添加到“DetailsList”中,但是直到用户在“CarsList”中选择不同的“Car”然后选择刚刚将详细信息添加到“DetailsList”中的“Car”时才可见”。

将“DetailsView”绑定ItemsSource到“CarView”ICollecitonView 中的“SelectedCar”以便在添加详细信息时刷新的正确方法是什么?

标签: c#wpf

解决方案


在搜索多个“相似”帖子几个小时后,我通过将“CarDetailList”从List<CarDetail> 更改为ObservableCollection<CarDetail>. 希望这对有类似情况的人有所帮助Model

 private ObservableCollection<CarDetail> _carDetailsList;
    public ObservableCollection<CarDetail> CarDetailsList
    {
        get { return _carDetailsList; }
        set { OnPropertyChanged(ref _carDetailsList, value); }
    }

和 SaveCarICommand动作:

 private void CarSave()
        {
            var newCar = new Car
            {
                Name = SelectedCar.Name,
                CarDetailsList = new List<Car.CarDetail>()
            };
          
            Cars.Add(newCar); // Add newCar to "CarList"
            CarView.Refresh();
            SelectedCar = newCar; // Selects the newly added item in the list
        }

推荐阅读