0

I have a TreeView that I am binding to an ItemsSource that creates a CheckBox for each item. Here is the xaml:

<TreeView x:Name="ReasonTreeView" Height="Auto" Background="Transparent"
        BorderThickness="0" IsTabStop="False"
        ItemsSource="{Binding Path=AnswerOptions}">
<TreeView.ItemTemplate>
    <HierarchicalDataTemplate DataType="{x:Type QSB:Answer}" ItemsSource="{Binding Path=AnswerOptions}">
        <StackPanel Orientation="Horizontal">
            <CheckBox Margin="0,5"
                        IsChecked="{Binding Path=IsSelected}"
                        IsEnabled="{Binding Path=Value,
                                            Converter={StaticResource ReasonValueToEnabledConverter}}"
                        Visibility="{Binding Path=AnswerOptions,
                                            Converter={StaticResource ParentNodeVisConverter}}" />
        </StackPanel>
    </HierarchicalDataTemplate>
</TreeView.ItemTemplate>

In my application I then create multiple instances of these. Depending on the instance of the TreeView, certain CheckBoxes need to be disabled so the user can not select them, however I'm uncertain of how I can access the individual items in the HierarchicalDataTemplate in the code.

After looking around for a while the only thing I can think of is to build the whole TreeView in the code behind instead of the xaml, but I would rather not have to resort to that. Is there anything else that I can do?

To help clarify my point and for illustrative purposes, this is essentially what I want to be able to do (in pseudocode): ReasonTreeView.ItemsSource[5].IsEnabled = false;

Which would disable the CheckBox (and any other controls in that HierarchicalDataTemplateItem) at index 5 of the TreeView's ItemsSource

Let me know if more information is needed

Saggio
  • 2,212
  • 6
  • 33
  • 50

2 Answers2

1

I meant that binding on the checkbox's isenabled property Path=Value. That Value member has to be bool and implement INotifyPropertyChanged then you can control IsEnabled from your model. Dont forget to add Mode=Twoway to your binding

Xelom
  • 1,615
  • 1
  • 13
  • 23
  • Apologies, I didn't see that you were talking about the `Value` member, I thought you were talking about the `AnswerOption` object. `Value` is a `string` which I pass into the converter. It adds a bit of complexity because everything is built dynamically at runtime, but now that I think about it, I actually might be able to pass in the the control housing the `TreeView` itself to the converter as well as the `Value` using `RelativeSource` and then enable/disable based on the name given to the control at runtime. – Saggio Mar 29 '13 at 17:09
  • Thanks! Marking this as the answer as thinking about using the converter is what helped me find the solution I needed. FYI if anyone else has a similar issue: I changed the converter to `IMultiValueConverter` and added another binding to the ancestor control's Name property (`Path="ScoreControlContainerName" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type abstract:ScoreControl}}"`) which I then used to find the correct instance(s) of the TreeView to disable the items that I needed. – Saggio Mar 29 '13 at 17:43
0

Instead of accessing the CheckBox through Control.ItemsSource property you should make the change in your underlying collection (that is itemssource of your control). After making the change notify the View (your Control) that data has been changed so update the control.

Implement INotifyPropertyChanged in your underlying class and after changing the Property (which is responsible for Enabled/Disabled) value Notify the View.

If you are not familiar with concepts of Data Binding and INotifyPropertyChanged, I would suggest you to read some basic tutorials about it. It is one of the major feature of WPF which makes life very easy for doing things like yours

Haris Hasan
  • 29,856
  • 10
  • 92
  • 122
  • Thanks, I'm very aware of `INotifyPropertyChanged` and data binding; My question is how I can access the individual items in the itemssource in the code behind. The above xaml is essentially a template for controls in my application; everything is built dynamically at runtime so I do not have the names at compile-time. – Saggio Mar 29 '13 at 17:02