C# 主/详细MVVM中的Wpf组合框

C# 主/详细MVVM中的Wpf组合框,c#,wpf,mvvm,combobox,wpf-controls,C#,Wpf,Mvvm,Combobox,Wpf Controls,我有如下MVVM主/详细信息: <Window.Resources> <DataTemplate DataType="{x:Type model:EveryDay}"> <views:EveryDayView/> </DataTemplate> <DataTemplate DataType="{x:Type model:EveryMonth}"> <views:EveryMonthView/> <

我有如下MVVM主/详细信息:

<Window.Resources>
<DataTemplate  DataType="{x:Type model:EveryDay}">
    <views:EveryDayView/>
</DataTemplate>

<DataTemplate  DataType="{x:Type model:EveryMonth}">
    <views:EveryMonthView/>
</DataTemplate>
</Window.Resources>

<Grid>
    <ListBox Margin="12,24,0,35" Name="schedules"
         IsSynchronizedWithCurrentItem="True"
         ItemsSource="{Binding Path=Elements}" 
         SelectedItem="{Binding Path=CurrentElement}" 
         DisplayMemberPath="Name" HorizontalAlignment="Left" Width="120"/>
    <ContentControl Margin="168,86,32,35" Name="contentControl1"
        Content="{Binding Path=CurrentElement.Schedule}" />
    <ComboBox Height="23" Margin="188,24,51,0" Name="comboBox1"
        VerticalAlignment="Top" 
           IsSynchronizedWithCurrentItem="True"
           ItemsSource="{Binding  Path=Schedules}"
           SelectedItem="{Binding Path=CurrentElement.Schedule}"
           DisplayMemberPath="Name" 
           SelectedValuePath="ID"
           SelectedValue="{Binding Path=CurrentElement.Schedule.ID}"/>
</Grid>

此窗口具有DataContext类:

public class MainViewModel : INotifyPropertyChanged {
    public MainViewModel() {
        elements.Add(new Element("first", new EveryDay("First EveryDay object")));
        elements.Add(new Element("second", new  EveryMonth("Every Month object")));
        elements.Add(new Element("third", new EveryDay("Second EveryDay object")));

        schedules.Add(new EveryDay());
        schedules.Add(new EveryMonth());
    }

    private ObservableCollection<ScheduleBase> _schedules = new
        ObservableCollection<ScheduleBase>();
    public ObservableCollection<ScheduleBase> Schedules {
        get {
            return _schedules;
        }

        set {
            schedules = value;
            this.OnPropertyChanged("Schedules");
        }
    }

    private Element _currentElement = null;
    public Element CurrentElement {
        get {
            return this._currentElement;
        }

        set {
            this._currentElement = value;
            this.OnPropertyChanged("CurrentElement");
        }
    }

    private ObservableCollection<Element> _elements = new
        ObservableCollection<Element>();
    public ObservableCollection<Element> Elements {
        get {
            return _elements;
        }

        set {
            elements = value;
            this.OnPropertyChanged("Elements");
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName) {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null) {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion
}
public类主视图模型:INotifyPropertyChanged{
公共主视图模型(){
元素。添加(新元素(“第一”,新每日(“第一每日对象”));
元素。添加(新元素(“第二个”,新的每个月(“每个月对象”));
元素。添加(新元素(“第三”,新的每日(“第二每日对象”));
添加(新的每日());
添加(neweverymonth());
}
私有可观测集合_计划=新
可观察收集();
公众可观察的收集时间表{
得到{
返回时间表;
}
设置{
附表=价值;
本条关于财产变更(“附表”);
}
}
私有元素_currentElement=null;
公共元素CurrentElement{
得到{
返回此值。\u currentElement;
}
设置{
此。_currentElement=值;
本.OnPropertyChanged(“CurrentElement”);
}
}
私有可观测集合_元素=新
可观察收集();
公共可观测集合要素{
得到{
返回元素;
}
设置{
元素=价值;
本协议项下的不动产变更(“要素”);
}
}
#区域INotifyProperty更改成员
公共事件属性更改事件处理程序属性更改;
受保护的无效OnPropertyChanged(字符串propertyName){
PropertyChangedEventHandler处理程序=PropertyChanged;
if(处理程序!=null){
处理程序(这是新的PropertyChangedEventArgs(propertyName));
}
}
#端区
}
其中一种观点:

<UserControl x:Class="Views.EveryDayView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid >
    <GroupBox Header="Every Day Data" Name="groupBox1" VerticalAlignment="Top">
        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <TextBox  Name="textBox2" Text="{Binding Path=AnyDayData}" />
        </Grid>
    </GroupBox>
</Grid>


组合框中的SelectedItem无法正常工作。我的代码中有任何可见的错误吗?

我通常做的是将
项控件的项绑定到
ICollectionView
(通常是ListCollectionView)而不是直接绑定到集合;我认为默认情况下,
ItemsControl
就是这样做的(创建默认的
ICollectionView
),但我可能错了

无论如何,这允许您使用
ICollectionView
CurrentItem
属性,该属性自动与
ItemsControl
中的选定项同步(如果控件的
IsSynchronizedWithCurrentItem
属性为true或null/default)。然后,当需要ViewModel中的当前项时,可以使用该项。您还可以使用ICollectionView上的
MoveCurrentTo…
方法设置所选项目

但当我重读这个问题时,我意识到你可能还有另一个问题;您有一个“默认”项的集合,需要一种将它们与特定实例相匹配的方法。但是如果重写对象的相等运算符,如果它们具有相同的类型,那么它们总是相等的,这将是一个坏主意,因为这有可能使其他代码非常混乱。我会考虑将类型信息提取到枚举中,并在返回枚举值之一的每个对象上放置只读属性。然后,可以将项目绑定到枚举值的集合,并将所选项目绑定到每个对象的枚举属性


如果您需要一个例子,请告诉我,我可能把解释弄得一团糟:)

您能提供更多细节吗?你在SelectedItem上看到了什么行为?它永远不会更新吗?不一致?我需要编辑在列表框中按ComboBox选择的元素属性计划,然后按UserControls选择。ListBox和ComboBox由ModelView中的CurrentElement绑定。要选择项目,请使用类型为Daily和EveryMonth的函数Equals()。这个函数比较ListBox中的元素.Schedule和ComboBox中的Schedule的指针,当然它们并不相等。我从ComboBox中期望一个类的对象被视为等价的行为。我可以给你发密码。谢谢你,本·冯·汉多夫。