简体   繁体   English

在WPF中将数据绑定到另一个xaml文件中的元素的最安全方法是什么

[英]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. 为了保持代码干净,我将TreeView移到了它自己的UserControl(我在几个地方都使用了此树)和xaml文件中。 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. 但是,当未选择任何treeviewitems时,我希望将此“添加”按钮显示为灰色。 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. 我可以绑定到完整的usercontrol并编写一个更复杂的转换器,但这似乎并不优雅。 Are there any simple solutions? 有没有简单的解决方案?

I would have hoped something along the lines of "ElementName=xamlFile.TargetElement" would have worked... 我本来希望像“ ElementName = xamlFile.TargetElement”这样的东西能起作用...

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. 如果创建命令并在UserControl中为其添加处理程序,则外部“添加按钮”可以使用该命令。

<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. 如果使用MVVM,则可以使用DelegateCommand或RelayCommand从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. 我将拥有一个Main.Xaml,其中将Main_ViewModel.Xaml设置为DataContext。 In Main.Xaml, I would have a MyTreeViewControl and a Button. 在Main.Xaml中,我将有一个MyTreeViewControl和一个Button。 For the MyTreeViewControl, I would have also created a MyTreeViewControl_ViewModel (which would use INotifyPropertyChanged). 对于MyTreeViewControl,我还将创建一个MyTreeViewControl_ViewModel(将使用INotifyPropertyChanged)。 In the Main_VeiwModel, I would create MyTreeViewControl_ViewModel property and instantiate it with a new instance of MyTreeViewControl_ViewModel. 在Main_VeiwModel中,我将创建MyTreeViewControl_ViewModel属性,并使用MyTreeViewControl_ViewModel的新实例对其进行实例化。 Then, in the Main.xaml, you could set the DataContext of your MyTreeViewControl to be that property. 然后,在Main.xaml中,可以将MyTreeViewControl的DataContext设置为该属性。 In the Main_ViewModel, you could have a Visibility property that the 'Add' buttons visibility is bound to. 在Main_ViewModel中,您可以具有“添加”按钮可见性绑定到的Visibility属性。 In the Main_ViewModel, you could subcribe to the 'PropertyChanged' event of the MyTreeViewControl_ViewModel. 在Main_ViewModel中,您可以订阅MyTreeViewControl_ViewModel的'PropertyChanged'事件。 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. 在这种情况下,您可以检查“ SelectedItem”是否发生了更改,如果发生更改,则可以重新评估并设置“添加”按钮的“可见性”属性。

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! 希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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