Могу ли я получить доступ из кода (ResourceDictionary) к именованному элементу управления?
Можно ли получить доступ из кода (ResourceDictionary) к именованному элементу управления?
Например, для меня необходимо создать множество диалогов для выбора папок. Диалог может содержать несколько строк для каждой папки, которая должна быть выбрана. Каждая строка состоит из: Label (Имя), TextBox (Выбранный путь) и Кнопка (открывает FileBrowserDialog).
Итак, теперь я хочу получить доступ к TextBox, когда FileBrowserDialog закончен. Но я не могу получить доступ к "SelectedFolderTextBox" из CodeBehind.
Есть ли лучший способ достичь того, что я хочу сделать?
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>
CodeBehind
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
}
}
2 ответа
Если у вас есть повторяющаяся группа элементов управления и немного связанных функций, имеет смысл создать элемент управления многократного использования:
Добавьте UserControl через диалоговое окно "Добавить элемент" проекта и используйте этот 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>
Вы должны быть в состоянии разыграть sender
аргумент Button
а затем бросить Parent
собственность Button
к StackPanel
и найти элементы управления в Children
коллекция StackPanel
, Что-то вроде этого:
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;
}
}
}