Wpf Combobox在Master/Detail MVVM中的应用

3
我有一个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
}

视图之一:

<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>

我的ComboBox中的SelectedItem无法正常工作。请问我的代码中是否有明显的错误?


你能提供更多细节吗?你在SelectedItem方面看到了什么行为?它从未被更新过吗?还是不一致? - Ben Von Handorf
我需要通过ComboBox和UserControls编辑在ListBox中选择的Schedule元素属性。ListBox和ComboBox由ModelView中的CurrentElement绑定。要选择项目,使用Types EveryDay和EveryMonth的Equals()函数的selectedItem of ComboBox。此函数比较ListBox中Element.Schedule和ComboBox中Schedule的指针,它们当然不相等。我期望从ComboBox中获得的行为是将同一类的对象视为等效。我可以发送代码。谢谢Ben Von Handorf。 - isak
1个回答

0
我通常会将ItemsControl的项绑定到ICollectionView(通常是ListCollectionView)而不是直接绑定到集合;我认为这就是ItemsControl默认情况下所做的(创建一个默认的ICollectionView),但我可能错了。
无论如何,这使您可以使用ICollectionViewCurrentItem属性,该属性会自动与ItemsControl中选择的项同步(如果控件的IsSynchronizedWithCurrentItem属性为true或null / default)。然后,当您需要ViewModel中的当前项时,可以使用它。您还可以使用ICollectionview上的MoveCurrentTo...方法设置所选项目。
但是当我重新阅读问题时,我意识到您可能有另一个完全不同的问题;您拥有一组“默认”项目,并需要一种方法将它们与特定实例匹配。然而,如果覆盖对象的相等运算符以始终将它们视为相等,则这将是一个坏主意,因为这可能会使其他代码非常混乱。我建议将类型信息提取到枚举中,并在每个对象上放置一个只读属性,返回枚举值之一。然后,您可以将项目绑定到枚举值的集合,将所选项目绑定到每个对象的枚举属性。
如果您需要示例,请告诉我,我可能已经搞砸了解释 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接