question

JoergDebus avatar image
0 Votes"
JoergDebus asked JoergDebus edited

How to bind to the SelectedItem property of a TreeView

The TreeView class offers:
[System.ComponentModel.Bindable(true)]
public object SelectedItem { get; }

I tried to code a Binding in XAML and in C# with a Binding mode OneWayToSource. My code in the viewmodel looks like this:

 Binding Binding = new Binding();
 Binding.Mode = BindingMode.OneWayToSource;
 Binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
 Binding.Source = this;
 Binding.Path = new PropertyPath( "SelectedItem" );
 Binding.NotifyOnSourceUpdated = true;
 var bindingExpression = BindingOperations.SetBinding( MainView.LoadTree, TreeView.SelectedItemProperty, Binding );

The last line ends with a SystemArgumentException "'SelectedItem' property cannot be data-bound. Parameter name: 'dp'".

AFAIK this is due to the code in the Binding.CreateBindingExpression method, which checks at start, whether the DP is readonly and throws that exception if true. Because the Binding is OneWayToSource this is no violation of the "readonly" tag of SelectedItem.

Any help is very welcome.





windows-wpf
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

DaisyTian-1203 avatar image
0 Votes"
DaisyTian-1203 answered DaisyTian-1203 commented

I think it is not a good way to bind data to TreeView.SelectedItemProperty, The SelectedItem property on the TreeView control is a read-only property and is set to an item when the IsSelected property value of the item TreeView is set to true, you could check it from the Microsoft document TreeView.SelectedItem. It is used to get the selected item in a TreeView, and it has no set method.

 [System.ComponentModel.Bindable(true)]
 public object SelectedItem { get; }

Update
You may misunderstand the refersouce code. Here is my understanding, if it doesn't give you help, please let me know.
In BindingExpression.cs 407 line, you can see:

 if ((fwMetaData != null && !fwMetaData.IsDataBindingAllowed) || dp.ReadOnly)
                 throw new ArgumentException(SR.Get(SRID.PropertyNotBindable, dp.Name), "dp");

If the dp is read only property , the will throw Exception. it means that, the read-only property can be used to bind data.

In binding.cs file 102 line:

 public static readonly RoutedEvent SourceUpdatedEvent =
                 EventManager.RegisterRoutedEvent("SourceUpdated",
                                         RoutingStrategy.Bubble,
                                         typeof(EventHandler<DataTransferEventArgs>),
                                         typeof(Binding));

It is a static readonly RoutedEvent not Property, it has AddHandler and RemoveHandler which could operation for the RountEvent. It does not like the property which is only has get method.


If the response is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Sorry Daisy, but your answer is not helpful. I'm looking for a solution for my problem not for advice.

In the published WPF-sources you can find in BindingExpression.cs starting at line 400 the code that raises my exception. It tests the ReadOnly-flag in the Binding object. So the final question is: is this a bug or is the official documentation wrong?

have code available, where a hand coded DP in a UserControl offers a readonly DP to which another Control can bind w/o problems. I tried to upload this sample, but unfortunately this Q/A implementation does not allow zip-files.

TIA and best regards
JD

0 Votes 0 ·

@JoergDebus
Sorry for not giving you help of my answer, could you show the link of WPF-sources for me to check? To upload the sample, you could upload it to GitHub and share link here.

0 Votes 0 ·

@DaisyTian-MSFT

Hi Daisy,
here is the link to the WPF-repository in GitHub: https://github.com/dotnet/wpf

In addition, I have uploaded some cs-files that implement the Binding functionality.
109553-binding.txtenter code here
109517-bindingbase.txt
109554-bindingexpression.txt
109518-bindingexpressionbase.txt109519-bindinggroup.txt
109508-bindinglistcollectionview.txtenter code here
109546-bindingoperations.txt



I cannot upload the sample to GitHub. No account there.

0 Votes 0 ·

@JoergDebus
I had updated the answer for you, please check.

0 Votes 0 ·
JoergDebus avatar image
0 Votes"
JoergDebus answered JoergDebus edited

@DaisyTian-MSFT

Hi Daisy,
after reading your updated answer, I decided to dig a little deeper into the topic. My conclusion is:

  1. Binding is possible to the "TreeView.SelectedItem" if it is bound as a source, not a target and OneWay is specified as the mode.

  2. This works both from within XAML or by code.

My conclusion is, that the exception raised when trying to bind as a target with OneWayToSource is a bug, because this is exactly the opposite of the alternative in 1.

Please find a XAML and a CS attached with a demo of the target. It displays a little tree with to TextBoxs at the top. The first shows the TextBox.Text bound to the TreeView.SelectedItem in XAML and the second shows the TextBox.Text bound to an simple property in WindowMain, which gets its content from a hand-coded DP in WindowMain bound to TreeView.SelectedItem as a source and using the PropertyChanged call back to set the simple property. This raises an PropertyChanged event which triggers the second TextBox.Text to be updated and displayed.

I had to rename the files to text. Pls. reverse this when using the files for testing (Framework 4.8)

This is my answer to the original question:
To bind properties in a ViewModel to a TreeView.SelectedItem, code these properties as a DPs and bind them with code the TreeView.SelectedItem with Mode=BindingMode.OneWay.

If you agree, pls. mark the answer as accepted.
Thanks for your patience.

Best regards
JD
111468-mainwindowxaml.txt111536-mainwindowcs.txt



mainwindowxaml.txt (2.3 KiB)
mainwindowcs.txt (5.1 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.