Question

The xaml view:

<DataGrid x:Name="dgInstances" SelectedItem="{Binding Path=Instance, Mode=OneWay}"
            ItemsSource="{Binding Instances}"> SelectionMode="Single"> ... etc.

The view-model:

public List<string> Instances
string instance;
public string Instance
{
    get
    {
        if (instance == null && instances.HasItems())
        {
            instance = instances[0];
        }
        if (instance != null)
        {
            return instance;
        }
        return null;
    }
    set
    {
        instance = value;
    }
}

The view-model-class implements INotifyPropertyChanged and after the Instances are fetched I give RaisePropertyChanged("Instance");.
The Instances are properly displayed in the datagrid, but the first item is not selected.
I don't want to add SelectedIndex=0 because it must be via binding.
And when I change the selection in the datagrid, the setter of the databound Instance is not used.
That is of course also a requirement.
It is a read-only list: only the selecteditem must be databound, not any values.

Was it helpful?

Solution

While I don't really use the WPF DataGrid, I have done in the past and seem to recollect that you can't Bind to the DataGrid.SelectedItem property... in all, it's a pretty useless property. However, I believe that you can Bind to the DataGrid.CurrentItem property which pretty much does the same thing.


UPDATE >>>

I just found that the WPF DataGrid SelectedItem binding stops working after item change post here on StackOverflow that mentions this.

Also, it seems that you can use the DataGrid.SelectedItem property in a UI element Binding, eg. to display it in a TextBox, so it's not completely useless... just mostly useless.


UPDATE 2 >>>

If you really need to access the DataGrid.SelectedItem property, you can create an AttachedProperty to handle the DataGrid.SelectionChanged event.


UPDATE 3 >>>

My collection classes extend a custom base class, which extends the ObservableCollection<T> class. My custom BaseColection<T> class has a CurrentItem property of type T. I use this property to Bind to the SelectedItem of the collection control. However, this has the same effect as adding a property into a view model of the same type as the items in the collection being displayed, but it's just more convenient:

<ListBox ItemsSource="{Binding AudioTracks}" 
    SelectedItem="{Binding AudioTracks.CurrentItem}" ... />

Then, if the items in the collection are small and contain all of the data that needs editing, I'll just use the AudioTracks.CurrentItem property for the editable fields on the right in my example image. However, if the data object has a lot of fields as in the image, then I just use the AudioTracks.CurrentItem.Id property value to send to the database to retrieve all of the values required for editing, whereas the AudioTracks items in the collection only hold a few values (because there can be 27,000+ of them in the collection.

Finally, regarding your linked example of a TreeView, I would normally use a custom SelectedItems Attached Property to Bind to the TreeView.SelectedItems property... If you search online, you can probably find someone's example code for this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top