WPF嵌套用户控件绑定 [英] WPF Nested Usercontrol bindings

查看:134
本文介绍了WPF嵌套用户控件绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想一个数值从窗口下来装订成用户控件内用户控件。但是,出于某种原因,内部用户控件甚至从来没有尝试尽可能我可以告诉绑定。

I'm trying to bind a value down from a Window into a UserControl inside a UserControl. But, for some reason, the inner UserControl never even attempts to bind as far as I can tell.

MainWindow.xaml

<Window x:Class="PdfExample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:PdfExample">
<Grid>
    <my:FileSystemBrowser HorizontalAlignment="Left" x:Name="fileSystemBrowser1" VerticalAlignment="Top" Height="311" Width="417" RootPath="C:\TFS\AE.Web.ezHealthQuoter.Common\1_Dev\Shared\Pdfs" />
</Grid>

FileSystemBrowser.xaml

<UserControl x:Class="PdfExample.FileSystemBrowser"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300" xmlns:my="clr-namespace:PdfExample">
<DockPanel>
    <my:FileSystemTree x:Name="fileSystemTree1" RootPath="{Binding Path=RootPath}" Width="150" />
    <ListBox DockPanel.Dock="Right" />
</DockPanel>

FileSystemBrowser.xaml.cs

    public partial class FileSystemBrowser : UserControl
{
    #region Static Members
    static FileSystemBrowser()
    {
        PropertyChangedCallback rootPathChangedCallback = new PropertyChangedCallback(OnRootPathChanged);
        PropertyMetadata metaData = new PropertyMetadata(rootPathChangedCallback);
        RootPathProperty = DependencyProperty.Register("RootPath", typeof(string), typeof(FileSystemBrowser), metaData);
    }

    static DependencyProperty RootPathProperty;

    public static void OnRootPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as FileSystemBrowser).RootPath = e.NewValue as string;
    }
    #endregion

    public string RootPath
    {
        get { return this.ViewModel.RootPath; }
        set { this.ViewModel.RootPath = value; }
    }

    public FileSystemBrowserViewModel ViewModel
    {
        get;
        protected set;
    }

    public FileSystemBrowser()
    {
        InitializeComponent();
        this.ViewModel = new FileSystemBrowserViewModel();
        this.DataContext = this.ViewModel;
    }
}

public class FileSystemBrowserViewModel : INotifyPropertyChanged
{
    private string _rootPath;
    public string RootPath
    {
        get { return _rootPath; }
        set { _rootPath = value; RaisePropertyChanged("RootPath"); }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

FileSystemTree.xaml

<UserControl x:Class="PdfExample.FileSystemTree"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<DockPanel>
    <TreeView SelectedValuePath="{Binding Path=SelectedValuePath, Mode=TwoWay}" HorizontalAlignment="Stretch" Name="treeView1" VerticalAlignment="Stretch" ItemsSource="{Binding RootFolder}" HorizontalContentAlignment="Left" VerticalContentAlignment="Top" Margin="0">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Folders}">                    
                <TextBlock Text="{Binding FolderName}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</DockPanel>

FileSystemTree.xaml.cs

    public partial class FileSystemTree : UserControl, INotifyPropertyChanged
{
    #region Static Members

    static DependencyProperty RootPathProperty;

    static FileSystemTree()
    {
        PropertyChangedCallback rootPathChangedCallback = new PropertyChangedCallback(OnRootPathChanged);
        PropertyMetadata metaData = new PropertyMetadata(rootPathChangedCallback);
        RootPathProperty = DependencyProperty.Register("RootPath", typeof(string), typeof(FileSystemTree), metaData);
    }

    public static void OnRootPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        (d as FileSystemTree).RootPath = e.NewValue as string;
    }

    #endregion

    public string RootPath
    {
        get { return this.ViewModel.RootPath; }
        set { this.ViewModel.RootPath = value; }
    }

    public FileSystemTreeViewModel ViewModel
    {
        get;
        protected set;
    }

    public FileSystemTree()
    {            
        InitializeComponent();
        this.ViewModel = new FileSystemTreeViewModel();
        this.DataContext = this.ViewModel;
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

public class FileSystemTreeViewModel : INotifyPropertyChanged
{
    public IFolder[] RootFolder
    {
        get
        {
            if (RootPath != null)
                return new IFolder[] { new FileSystemFolder(RootPath) };

            return null;
        }
    }

    private string _rootPath;
    public string RootPath
    {
        get { return _rootPath; }
        set
        {
            _rootPath = value;
            RaisePropertyChanged("RootPath");
            RaisePropertyChanged("RootFolder");
        }
    }

    private string _selectedValuePath;
    protected string SelectedValuePath
    {
        get { return _selectedValuePath; }
        set { _selectedValuePath = value; }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

我知道树的作品,因为如果我只是把树中MainWindow.xaml,它的罚款。但由于某些原因,从MainWindow.xaml的ROOTPATH​​值被绑定到FileSystemBrowser并停止在那里。它从来没有使得它一路下跌到FileSystemTree。我缺少什么?

I know that the tree works, because if I just put the tree inside MainWindow.xaml, it's fine. But for some reason, the RootPath value from MainWindow.xaml gets bound into FileSystemBrowser and stops there. It never makes it all the way down to FileSystemTree. What am I missing?

推荐答案

有就是一些信息,以便确定,但我认为这个问题是没有设置的DataContext。尝试相对绑定,这将可能有所帮助。在FileSystemBrowser.xaml更改绑定如下:

There is to few information to be certain, but I think the problem is the DataContext that is not set. Try relative bindings, this will probably help. In FileSystemBrowser.xaml change the binding as follows:

<my:FileSystemTree x:Name="fileSystemTree1" 
    RootPath="{Binding Path=RootPath,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}" 
    Width="150" />     

另一种可能性是,设置的UserControls此引用到DataContext。这也应该有所帮助。

Another possibility would be to set the UserControls this-reference to the DataContext. This should also help.

这篇关于WPF嵌套用户控件绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆