开发者

Wpf Combobox in Master/Detail MVVM

开发者 https://www.devze.com 2022-12-24 03:37 出处:网络
I have MVVM master /details like this: <Window.Resources> <DataTemplateDataType=\"{x:Type model:EveryDay}\">

I have MVVM master /details like this:

<Window.Resources>
<DataTemplate  DataType="{x:Type model:EveryDay}">
    <views:EveryDayView/>
</DataTemplate&g开发者_如何转开发t;

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

This Window has DataContext class:

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
}

One of Views:

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

My SelectedItem in ComboBox doesn't works correctly. Are there any visible errors in my code?


What I usually do is bind the items of an ItemsControl to an ICollectionView (usually ListCollectionView) instead of directly to a collection; I think that's what the ItemsControl does by default anyway (creates a default ICollectionView), but I might be wrong.

Anyway, this allows you to work with the CurrentItem property of the ICollectionView, which is automatically synchronized with the selected item in an ItemsControl (if the IsSynchronizedWithCurrentItem property of the control is true or null/default). Then, when you need the current item in the ViewModel, you can use that instead. You can also set the selected item by using the MoveCurrentTo... methods on the ICollectionView.

But as I re-read the question I realize you may have another problem altogether; you have a collection of 'default' items and need a way to match them to specific instances. It would however be a bad idea to override the equality operators of the objects to consider them always equal if they are of the same type, since that has the potential to make other code very confusing. I would consider extracting the type information into an enum, and put a read-only property on each object returning one of the enum values. Then you can bind the items to a collection of the enum values, and the selected item to the enum property of each object.

Let me know if you need an example, I may have made a mess of the explanation :)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号