私は、UserControl内のUserControlにWindowから値をバインドしようとしています。しかし、何らかの理由で、内部のUserControlは、私が知る限り、バインドしようとしません。WPFネストされたユーザーコントロールバインド
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>
FileSystemBrows er.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に至ることはありません。私は何が欠けていますか?
投稿を更新しました。私は各xamlクラスのDataContextをカスタムオブジェクトに設定しています。 FileSystemBreeserで割り当てられたDataContextのプロパティが更新されると、FileSystemTreeの更新がトリガーされるたびに、FileSystemBreeserでバインドされたFileSystemBreeserで宣言されたため、私はその印象を受けました。 – Xaiter
このアップデートを伝播するバインディングはありません。さらに、コンストラクタで 'DataContext'がハード設定されていると、探しているものが得られない可能性があります。 – user7116
コントロールごとにDataContextを割り当てない場合は、すべてデフォルトでWindowレベルで割り当てられたものになります。これは、すべての入れ子になったコントロールが値のために期待していることをWindowに完全に認識させるDataContextオブジェクトを作成する必要があることを意味します。これは、特にネストされたユーザコントロールでの双方向バインディングを混乱させるときに、コントロールの再利用のポイントを打ち負かしているようです。 WPFコントロールを構築する方法についていくつかの根本的な欠点がありますか? – Xaiter