我可以从(ResourceDictionary 的)隐藏代码访问命名控件吗?
Can I get access from code behind (of a ResourceDictionary) to a named control?
是否可以从(ResourceDictionary 的)隐藏代码访问命名控件?
例如对我来说,有必要创建很多文件夹选择对话框。对于必须选择的每个文件夹,对话框可能包含几行。
每行包括:标签(名称)、文本框(选择的路径)和按钮(打开 FileBrowserDialog)。
所以现在我想在 FileBrowserDialog 完成时访问 TextBox。但是我无法从 CodeBehind 访问 "SelectedFolderTextBox"。
有没有更好的方法来实现我想做的事情?
XAML
<ResourceDictionary ...>
...
<StackPanel x:Key="FolderSearchPanel"
x:Shared="False">
<Label Content="Foldername"/>
<TextBox x:Name="SelectedFolderTextBox"
Text="C:\Folder\Path\"/>
<Button Content="..."
Click="Button_Click"/>
</StackPanel>
</ResourceDictionary>
代码隐藏
private void Button_Click(object sender, RoutedEventArgs e)
{
// Initialize and show
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
// Process result
if (result == System.Windows.Forms.DialogResult.OK)
{
string selectedPath = dialog.SelectedPath;
SelectedFolderTextBox.Text = selectedPath; // THIS DOES NOT WORK
// since I don't have access to it
// but describes best, what I want to do
}
}
您应该能够将 sender
参数转换为 Button
,然后将 Button
的 Parent
属性 转换为 StackPanel
并在 StackPanel
的 Children
集合中找到控件。像这样:
private void Button_Click(object sender, RoutedEventArgs e)
{
// Initialize and show
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
// Process result
if (result == System.Windows.Forms.DialogResult.OK)
{
string selectedPath = dialog.SelectedPath;
Button clickedButton = sender as Button;
StackPanel sp = clickedButton.Parent as StackPanel;
if (sp != null)
{
TextBox SelectedFolderTextBox = sp.Children.OfType<TextBox>().FirstOrDefault(x => x.Name == "SelectedFolderTextBox");
if (SelectedFolderTextBox != null)
SelectedFolderTextBox.Text = selectedPath;
}
}
}
当您有一组重复的控件和一些相关功能时,创建可重用控件是有意义的:
通过项目 "Add Item" 对话框添加用户控件并使用此 xaml 和代码:
<UserControl x:Class="WpfDemos.FolderPicker"
x:Name="folderPicker"
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="75" d:DesignWidth="300">
<StackPanel>
<Label Content="{Binding Path=Title, ElementName=folderPicker}"/>
<TextBox x:Name="SelectedFolderTextBox"
Text="{Binding Path=FullPath, ElementName=folderPicker,
UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="..." Click="PickClick"/>
</StackPanel>
</UserControl>
public partial class FolderPicker : UserControl
{
public FolderPicker()
{
InitializeComponent();
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(
"Title", typeof (string), typeof (FolderPicker), new PropertyMetadata("Folder"));
public string Title
{
get { return (string) GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty FullPathProperty = DependencyProperty.Register(
"FullPath", typeof (string), typeof (FolderPicker), new FrameworkPropertyMetadata(@"C:\", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string FullPath
{
get { return (string) GetValue(FullPathProperty); }
set { SetValue(FullPathProperty, value); }
}
private void PickClick(object sender, RoutedEventArgs e)
{
using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
FullPath = dialog.SelectedPath;
}
}
}
可从代码隐藏访问 TextBox。依赖属性 Title
和 FullPath
允许为不同的用途自定义控件并创建与视图模型的绑定(对于声明为资源的控件组,您无法做到这一点)。例子
查看模型:
public class MyViewModel
{
public string Src { get; set; }
public string Target { get; set; }
}
查看:
public MyWindow()
{
InitializeComponent();
this.DataContext = new MyViewModel { Src = "C:", Target = "D:" }
}
<StackPanel>
<wpfDemos:FolderPicker Title="Source" FullPath="{Binding Path=Src}" />
<wpfDemos:FolderPicker Title="Destination" FullPath="{Binding Path=Target}"/>
</StackPanel>
是否可以从(ResourceDictionary 的)隐藏代码访问命名控件?
例如对我来说,有必要创建很多文件夹选择对话框。对于必须选择的每个文件夹,对话框可能包含几行。 每行包括:标签(名称)、文本框(选择的路径)和按钮(打开 FileBrowserDialog)。
所以现在我想在 FileBrowserDialog 完成时访问 TextBox。但是我无法从 CodeBehind 访问 "SelectedFolderTextBox"。
有没有更好的方法来实现我想做的事情?
XAML
<ResourceDictionary ...>
...
<StackPanel x:Key="FolderSearchPanel"
x:Shared="False">
<Label Content="Foldername"/>
<TextBox x:Name="SelectedFolderTextBox"
Text="C:\Folder\Path\"/>
<Button Content="..."
Click="Button_Click"/>
</StackPanel>
</ResourceDictionary>
代码隐藏
private void Button_Click(object sender, RoutedEventArgs e)
{
// Initialize and show
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
// Process result
if (result == System.Windows.Forms.DialogResult.OK)
{
string selectedPath = dialog.SelectedPath;
SelectedFolderTextBox.Text = selectedPath; // THIS DOES NOT WORK
// since I don't have access to it
// but describes best, what I want to do
}
}
您应该能够将 sender
参数转换为 Button
,然后将 Button
的 Parent
属性 转换为 StackPanel
并在 StackPanel
的 Children
集合中找到控件。像这样:
private void Button_Click(object sender, RoutedEventArgs e)
{
// Initialize and show
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
// Process result
if (result == System.Windows.Forms.DialogResult.OK)
{
string selectedPath = dialog.SelectedPath;
Button clickedButton = sender as Button;
StackPanel sp = clickedButton.Parent as StackPanel;
if (sp != null)
{
TextBox SelectedFolderTextBox = sp.Children.OfType<TextBox>().FirstOrDefault(x => x.Name == "SelectedFolderTextBox");
if (SelectedFolderTextBox != null)
SelectedFolderTextBox.Text = selectedPath;
}
}
}
当您有一组重复的控件和一些相关功能时,创建可重用控件是有意义的:
通过项目 "Add Item" 对话框添加用户控件并使用此 xaml 和代码:
<UserControl x:Class="WpfDemos.FolderPicker"
x:Name="folderPicker"
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="75" d:DesignWidth="300">
<StackPanel>
<Label Content="{Binding Path=Title, ElementName=folderPicker}"/>
<TextBox x:Name="SelectedFolderTextBox"
Text="{Binding Path=FullPath, ElementName=folderPicker,
UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="..." Click="PickClick"/>
</StackPanel>
</UserControl>
public partial class FolderPicker : UserControl
{
public FolderPicker()
{
InitializeComponent();
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(
"Title", typeof (string), typeof (FolderPicker), new PropertyMetadata("Folder"));
public string Title
{
get { return (string) GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty FullPathProperty = DependencyProperty.Register(
"FullPath", typeof (string), typeof (FolderPicker), new FrameworkPropertyMetadata(@"C:\", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string FullPath
{
get { return (string) GetValue(FullPathProperty); }
set { SetValue(FullPathProperty, value); }
}
private void PickClick(object sender, RoutedEventArgs e)
{
using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
FullPath = dialog.SelectedPath;
}
}
}
可从代码隐藏访问 TextBox。依赖属性 Title
和 FullPath
允许为不同的用途自定义控件并创建与视图模型的绑定(对于声明为资源的控件组,您无法做到这一点)。例子
查看模型:
public class MyViewModel
{
public string Src { get; set; }
public string Target { get; set; }
}
查看:
public MyWindow()
{
InitializeComponent();
this.DataContext = new MyViewModel { Src = "C:", Target = "D:" }
}
<StackPanel>
<wpfDemos:FolderPicker Title="Source" FullPath="{Binding Path=Src}" />
<wpfDemos:FolderPicker Title="Destination" FullPath="{Binding Path=Target}"/>
</StackPanel>