【发布时间】:2011-01-19 21:48:00
【问题描述】:
我正在尝试将一个值从 Window 绑定到 UserControl 内的 UserControl。但是,由于某种原因,据我所知,内部 UserControl 甚至从未尝试绑定。
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。我错过了什么?
【问题讨论】: