0

Ok so this is kinda hard to explain. I have a view which has a tree and has a form. The tree is bound to 2 different observable collections.

<TreeView FontFamily="Calibri" FontSize="16" Name="tree" Margin="3" Grid.Row="1" Grid.Column="0"  Height="950" VerticalAlignment="Top" Grid.ColumnSpan="2"

              ItemsSource="{Binding Path=Org, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItemChanged="tree_SelectedItemChanged"  >             

    <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Path=Org_Sredstva}">
                <TextBlock Text="{Binding Path=Organizacije_Naziv}"/>
                <HierarchicalDataTemplate.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=Ossr_Naziv}"/>
                    </DataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>

Now then next to the tree there is a form. And the form is supposed to be bound to a third observable collection that changes depending on selecteditem of tree.

<Grid Grid.Row="2" Grid.Column="2" Margin="5" DataContext="{Binding ElementName=tree, Path=SelectedItem}">

As you can see the binding is to the tree which is bound to a different observable collection.

 <extToolkit:WatermarkTextBox x:Name="RadnoVrijeme" Grid.Row="1"
                     Grid.Column="1" 
                     Grid.ColumnSpan="2"
                     HorizontalAlignment="Left"
                     VerticalAlignment="Bottom"
                       Width="100"
                     Height="25"
                     Padding="3" 
                     Margin="3"
                     AcceptsReturn="True" 
                     Validation.ErrorTemplate="{StaticResource ValidationTemplate}"
                     Validation.Error="Validation_Error">
                    <extToolkit:WatermarkTextBox.Watermark>
                        <StackPanel Orientation="Horizontal">
                            <TextBox Text="Radno Vrijeme" Margin="4,2,2,0" FontWeight="Regular" Foreground="Silver" BorderThickness="0"/>
                        </StackPanel>
                    </extToolkit:WatermarkTextBox.Watermark>
                    <extToolkit:WatermarkTextBox.Text>
                        <Binding Path="Opr_RadnoVrijeme" UpdateSourceTrigger="PropertyChanged" NotifyOnValidationError="True">
                            <Binding.ValidationRules>
                                <validation:InputLenghtRule MinLength="10" MaxLength="250" ValidatesOnTargetUpdated="True"/>
                            </Binding.ValidationRules>
                        </Binding>
                    </extToolkit:WatermarkTextBox.Text>
                </extToolkit:WatermarkTextBox>

This is a textbox and it is bound to a property on the third collection but it doesn't work obviously because that collection is never set as itemssource anywhere.

The workaround I found is to in codebehind set every textbox individually so

this.View.RadnoVrijeme.Text = opr.Opr_RadnoVrijeme;

Where the left side of the equation is the text property of the textbox and the right side is the collection.property. This works but I don't like it and was hoping there was a way to actually bind this?

Dino Kantardzic
  • 97
  • 1
  • 4
  • 13

1 Answers1

0

You should definetely have a look at MVVM. It utilize modular design, where your View is consisting of multiple Views controlled by ViewModels. Then it's easy to solve any kind of dependency (relation? selection?) problem.

In your case you are trying to bind to SelectedItem directly, while in MVVM you will handle selection and then you have possibility to rise notification of related property change, which will cause update of corresponding View element automatically.

Here is a generic example:

ItemVM _selectedItem;
public ItemVM SelectedItem
{
    get { return _selectedItem; }
    set
    {
        _selectedItem = value;
        OnPropertyChanged();
        // trigger update in the view
        OnPropertyChanged(nameof(SomeRelatedProperty));
    }
}

// bind TextBlock.Text to that property
public string SomeRelatedProperty
{
    get
    {
        // some logic based on selected item
        if(SelectedItem.SomeProperty == SomeValue)
            return "a";
        ...
        return "b";
    }
}

The cooler thing if SelectedItem already provides value as one of property (because it's a ViewModel), then assuming all ViewModels implement INotifyPropertyChanged you can simply bind to that property directly and whenever selected item is changed the view will be updated to display that property too:

<TextBlock Text="{Binding SelectedItem.SomeProperty} ... / >

As for error you are getting:

System.Windows.Data Error: 40 : BindingExpression path error: 'Opr_RadnoVrijeme' property not found on 'object' ''Organizacije' (HashCode=23451234)'. BindingExpression:Path=Opr_RadnoVrijeme; DataItem='Organizacije' (HashCode=23451234); target element is 'WatermarkTextBox' (Name='RadnoVrijeme'); target property is 'Text' (type 'String')

Try binding (pretty unsure, you didn't provide ViewModels to figure that out):

<WatermarkTextBox Text="{Binding SelectedItem.Opr_RadnoVrijeme, RelativeSource={RelativeSource FindAncestor, AncestorType=TreeView}}" ... />
Community
  • 1
  • 1
Sinatr
  • 20,892
  • 15
  • 90
  • 319
  • Yeah but the selected item doesn't contain that property because its a different collection for a different class. Also I implement CastleActiveRecords with Model view presenter pattern or at least I tried to. I implement Inotify. See this is my issue sort of BindingExpression path error: 'Opr_Povrsina' property not found on 'object' ''Organizacije' This is my output error and the object Organizacije does not hold the property Opr_Povrsina the object Opremljenosti does hold it but I don't know how to bind to it because I need the Organizacije as well for the tree. – Dino Kantardzic Mar 23 '16 at 09:52
  • Here u can see I use Property Change on my 2 collections but it just doesn't work for me, im doing something wrong... public ObservableCollection Oprema { get { return _oprema; } set { _oprema = value; OnPropertyChanged("Oprema"); } } public ObservableCollection Org { get { return _organizacije; } set { _organizacije = value; OnPropertyChanged("Org"); } } – Dino Kantardzic Mar 23 '16 at 10:00
  • You haven't shown hierarchy of classes, but anyhow `SelecteItem` should provide information used to display text, then using first approach (rising notification for related property) can be used to decide what value to display. I don't know what is `CastelActiveRecords` (MVP?), but wpf is associated with MVVM for many, where ViewModel typically implement `INotifyPropertyChanged`. Can you show your ViewModels? And your current method to set text value too please. – Sinatr Mar 23 '16 at 10:00
  • That error you mention earlier could be a simple binding path error (easily solvable with `RelativeSource`). Can you post a complete error into question? – Sinatr Mar 23 '16 at 10:03
  • I don't think it is because it gives me for every textbox I have so like 10,12 of these System.Windows.Data Error: 40 : BindingExpression path error: 'Opr_RadnoVrijeme' property not found on 'object' ''Organizacije' (HashCode=23451234)'. BindingExpression:Path=Opr_RadnoVrijeme; DataItem='Organizacije' (HashCode=23451234); target element is 'WatermarkTextBox' (Name='RadnoVrijeme'); target property is 'Text' (type 'String') – Dino Kantardzic Mar 23 '16 at 10:07
  • I feel like the issue is the 3 collection binding. Where the tree uses 2 collections and then the third collection should be used by the form but i dunno how to bind that third collection to the form. The grid doesn't have an itemssource property, it has datacontext but I tried setting that with no luck and anyway its already set to the tree selected item – Dino Kantardzic Mar 23 '16 at 10:08
  • Don't set `DataContext` (I wasn't sure it will work, now you confirmed it). Use `RelativeSource` in bindings (which in turn have `DataContext.` string added to binding `Path`) to access ViewModel of higher level. [Edit](http://stackoverflow.com/posts/36173818/edit) your question instead of putting code/errors into comments (for other readers). – Sinatr Mar 23 '16 at 10:12
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/107117/discussion-between-dino-kantardzic-and-sinatr). – Dino Kantardzic Mar 23 '16 at 10:22