views:

44

answers:

2

I have an application which shows a Tree where can select nodes of the tree and add them to a list. To keep the code clean I have moved the TreeView into it's own UserControl(I use this tree in several places) and xaml file. To add a node to the list I have an 'add' button. However I want to gray-out this 'add' button when none of the treeviewitems are selected. What is the wisest way to do this. I can bind to the complete usercontrol and write a more complicated converter, but this seems inelegant. Are there any simple solutions?

I would have hoped something along the lines of "ElementName=xamlFile.TargetElement" would have worked...

A: 

Here's how I would do it. I would have a Main.Xaml, which would have a Main_ViewModel.Xaml set as it's DataContext. In Main.Xaml, I would have a MyTreeViewControl and a Button. For the MyTreeViewControl, I would have also created a MyTreeViewControl_ViewModel (which would use INotifyPropertyChanged). In the Main_VeiwModel, I would create MyTreeViewControl_ViewModel property and instantiate it with a new instance of MyTreeViewControl_ViewModel. Then, in the Main.xaml, you could set the DataContext of your MyTreeViewControl to be that property. In the Main_ViewModel, you could have a Visibility property that the 'Add' buttons visibility is bound to. In the Main_ViewModel, you could subcribe to the 'PropertyChanged' event of the MyTreeViewControl_ViewModel. In that event, you could check to see if your 'SelectedItem' is what changed, if so, you could re-evaluate and set the Visibility property for your add button.

Sorry, I didn't have time to give a code example. I could possibly right something up for you later if you really needed it. Hope this helps!

JSprang
A: 

Commands provide automatic disabling of buttons using them when the command cannot execute. If you create a command and add handlers for it in your UserControl the external Add Button can use the command.

<local:TreeViewControl x:Name="Tree"/>
<Button Content="Add" Command="{x:Static local:TreeViewControl.AddCommand}" CommandTarget="{Binding ElementName=Tree}"/>

Command creation and hookup:

public partial class TreeViewControl : UserControl
{
    public static RoutedCommand AddCommand { get; private set; }

    static TreeViewControl()
    {
        AddCommand = new RoutedCommand("AddCommand", typeof(TreeViewControl));
    }

    public TreeViewControl()
    {
        InitializeComponent();

        CommandBindings.Add(new CommandBinding(AddCommand, AddExecuted, AddCanExecute));
    }

    public void AddExecuted(object sender, ExecutedRoutedEventArgs e)
    {
    }

    public void AddCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = false; // your logic here
    }
}

If using MVVM you can use DelegateCommand or RelayCommand to do similar things from a ViewModel.

John Bowen
Thanks, exactly what I was searching for... I did find it last week though, but still...
ate_f