2
votes

I have a TreeView which I have bound to a ViewModel called RootViewModel which has a collection of ViewModels ChildViewModel which has a collection of ViewModels GrandhChildViewModel.

I have a text box next to the tree view.

I want to bind the text box's text to a specific property of the selected item only when a GrandChildViewModel is selected in the tree. If a GrandChildViewModel is not selected, I want the text in the textbox to be empty. I'd also like to have it so if I change the text in the TextBox when a GrandChild is selected it will update the text for that item in the treeview. (I'm assuming 2 way binding between the viewmodel<->textbox and viewmodel<->treeview

|------------------|
| - Root           |
|   - Child        |     |---------------------------------|
|     - GrandChild |     | Selected GrandChild's Property  |
|     - GrandChild |     |---------------------------------|
|     - GrandChild |                            ^
|   - Child        |                            |
|     - GrandChild |<----- Selected GrandChild -|
|                  |
|------------------|

Sample ViewModels:

public class RootViewModel : INotifyPropertyChanged
{
    public ObservableCollection<ChildViewModel> Children{ get; set; }
    public bool IsSelected{ get { /* code */ } set { /* code */ OnPropertyChanged("IsSelected"); }
}
public class ChildViewModel : INotifyPropertyChanged
{
    public ObservableCollection<GrandChildViewModel> GrandChildren{ get; set; }
    public bool IsSelected{ get { /* code */ } set { /* code */ OnPropertyChanged("IsSelected"); }
    public string SomeProperty{ get { /* code */ } set { /* code */ OnPropertyChanged("SomeProperty"); }
}
public class GrandChildViewModel : INotifyPropertyChanged
{
    public bool IsSelected{ get { /* code */ } set { /* code */ OnPropertyChanged("IsSelected"); }
    public bool SomeOtherProperty{ get { /* code */ } set { /* code */ OnPropertyChanged("SomeOtherProperty"); }
}

My attempt's so far in Xaml:

<TextBox>
    <TextBox.Style>
        <Style TargetType="TextBox">
            <Style.Triggers>
                &ltDataTrigger Value="True">
                    <DataTrigger.Binding>
                         <Binding Converter="{StaticResource myConverter}" ElementName="myTreeView" Path="SelectedItem" Mode="TwoWay" />
                    </DataTrigger.Binding>
                    <DataTrigger.Setters>
                        <Setter Property="Text" Value="{Binding Path=SomeOtherProperty}" />
                    </DataTrigger.Setters>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBox.Style>
</TextBox>

Also tried

<TextBox Text={Binding ElementName=myTreeView, Path=SelectedItem, Converter={StaticResource myConverter}, Mode=TwoWay}" />

Many Thanks in advance.

Update

I found that this is throwing an exception because TwoWay DataBinding on SelectedItem is not allowed.

1

1 Answers

1
votes

Thanks to this post I was able to get this to work. I set the StackPanel around the text box to bind to the selected item, then bound the text box to the property I care about.

<StackPanel DataContext={Binding ElementName=myTreeView, Path=SelectedItem}">
    <TextBox Text={Binding Path=SomeOtherProperty, Mode=TwoWay}" />
</StackPanel>

Works like a charm.