1

I've got DataGrid bound to an ObservableCollection<> in its ViewModel:

<DataGrid ItemsSource="{Binding Path=Data}" SelectedItem="{Binding Path=CurrentItem}" />

ViewModel:

    public ObservableCollection<TestModel> Data { get; set; }

    private TestModel _currentItem;

    public TestModel CurrentItem
    {
        get { return _currentItem; }
        set
        {
            _currentItem = value;
            RaisePropertyChanged("CurrentItem");
        }
    }

Now what I want is, that the DataGrid will preselect the first Row right on Form-startup. So I put the following in my test-code inside the constructor:

    Data = new ObservableCollection<TestModel>
    {
        new TestModel() { Property1 = Guid.NewGuid().ToString() },
        new TestModel() { Property1 = Guid.NewGuid().ToString() },
        new TestModel() { Property1 = Guid.NewGuid().ToString() }
    };
    CurrentItem = Data[0];

The data is displayed but the first row isn't selected by the grid. Even if I set the binding to TwoWay, it won't work.

If I remove the SelectedItem-binding in XAML and add the following in Code-behind, it works well:

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        var m = this.DataContext as MainViewModel;
        grid.SelectedItem = m.CurrentItem;
    }
9
  • Can you try if selecting a row in DataGrid update your view model's CurrentItem property? Commented Nov 30, 2011 at 14:13
  • @Amit If you want to know, if the CurrentItem-setter is called when I click a row in the grid then the answer is yes, it is. Even if I leave out the setting for the binding-direction. Commented Nov 30, 2011 at 14:38
  • 1
    I noticed the same problem and ended up using the same workaround. Commented Nov 30, 2011 at 17:41
  • @RQDQ Thanks for that. I'm a little bit charmer now ;-) Commented Nov 30, 2011 at 19:31
  • 1
    How/where do you set your MainViewModel to the DataContext? Because I've created a small repro based on your code and the pre-selection is working fine. Commented Nov 30, 2011 at 19:50

1 Answer 1

1

What's happening is that your VM is being assigned to the data context before the window is initialized and therefore never receives the message that the CurrentItem has changed because it was changed before it loaded.

What I do, is pass in the view model into View's constructor and set it after the InitializeComponent() function is called. Because I am using Prism I am using inversion of control (IOC) and Prism knows to input my VM into the constructor. If you are instantiating your view and view model yourself, you can just pass in the view model. I ran into the same issue and this works.

    public MyView(IMyVM viewModel)
    {
        InitializeComponent();
        this.DataContext = viewModel;
    }

By the way, in working with MVVM, I see no reason not to pass in the ViewModel into the View because the view is dependent on it anyway. I know some people feel differently but it is either this or you will have to so some type of refresh of the datacontext in the Window_Loaded event.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.