简体   繁体   中英

What is the safest way of databinding to an element in another xaml file in WPF

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...

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.

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM