C# 以浏览按钮作为用户控件的WPF路径文本框
我正在尝试制作一个非常简单的UserControl,它有一个路径,您可以在文本框中键入,也可以通过单击浏览按钮找到。 我尝试使用依赖属性来实现这一点,但绑定到依赖属性时,这并不能完全起作用 这里是我的xaml:C# 以浏览按钮作为用户控件的WPF路径文本框,c#,wpf,xaml,user-controls,dependency-properties,C#,Wpf,Xaml,User Controls,Dependency Properties,我正在尝试制作一个非常简单的UserControl,它有一个路径,您可以在文本框中键入,也可以通过单击浏览按钮找到。 我尝试使用依赖属性来实现这一点,但绑定到依赖属性时,这并不能完全起作用 这里是我的xaml: <UserControl x:Class="PathSelector.PathSelector" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x=
<UserControl x:Class="PathSelector.PathSelector"
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"
xmlns:local="clr-namespace:PathSelector">
<DockPanel Height="28">
<Button DockPanel.Dock="Right" Padding="5" Margin="5 0 0 0"
FontWeight="Bold"
Content="..."
Click="BrowseButton_Click" />
<Grid>
<TextBox
HorizontalAlignment="Stretch" VerticalAlignment="Center"
x:Name="SelectedPathTxtBox"
LostKeyboardFocus="SelectedPathTxtBox_LostKeyboardFocus" />
</Grid>
</DockPanel>
</UserControl>
这是代码背后:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
namespace PathSelector
{
/// <summary>
/// A simple input for path, with browse button
/// </summary>
public partial class PathSelector : UserControl
{
public PathSelector()
{
InitializeComponent();
}
private void BrowseButton_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog fileDialog = new System.Windows.Forms.OpenFileDialog();
fileDialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
SelectedPathTxtBox.Text = fileDialog.FileName;
}
}
#region Dependency Properties
public string SelectedPath
{
get { return (string)GetValue(SelectedPathProperty); }
set { SetValue(SelectedPathProperty, value); }
}
public static readonly DependencyProperty SelectedPathProperty =
DependencyProperty.Register(
"SelectedPath",
typeof(string),
typeof(PathSelector),
new FrameworkPropertyMetadata(new PropertyChangedCallback(SelectedPathChanged))
{
BindsTwoWayByDefault = true,
DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});
private static void SelectedPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MessageBox.Show("Changed!");
// How to update the values here??
}
#endregion
private void SelectedPathTxtBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
SelectedPath = SelectedPathTxtBox.Text;
}
}
}
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
使用System.Windows.Input;
命名空间路径选择器
{
///
///一个简单的路径输入,带有浏览按钮
///
公共部分类路径选择器:UserControl
{
公共路径选择器()
{
初始化组件();
}
私有无效浏览按钮单击(对象发送者,路由目标)
{
System.Windows.Forms.OpenFileDialog fileDialog=新建System.Windows.Forms.OpenFileDialog();
fileDialog.Filter=“txt文件(*.txt)|*.txt|所有文件(*.*)|*.”;
if(fileDialog.ShowDialog()==System.Windows.Forms.DialogResult.OK)
{
SelectedPathTxtBox.Text=fileDialog.FileName;
}
}
#区域依赖属性
公共字符串选择路径
{
get{return(string)GetValue(SelectedPathProperty);}
set{SetValue(SelectedPathProperty,value);}
}
公共静态只读从属属性SelectedPathProperty=
从属属性。寄存器(
“SelectedPath”,
类型(字符串),
类型(路径选择器),
新的FrameworkPropertyMetadata(新的PropertyChangedCallback(SelectedPathChanged))
{
BindsTwoWayByDefault=true,
DefaultUpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged
});
私有静态void SelectedPathChanged(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
MessageBox.Show(“已更改!”);
//如何更新此处的值??
}
#端区
private void SelectedPathTxtBox\u LostKeyboardFocus(对象发送器,KeyboardFocusChangedEventArgs e)
{
SelectedPath=SelectedPathTxtBox.Text;
}
}
}
我希望以后像这样使用此UserControl:
<pathselector:PathSelector
SelectedPath="{Binding PathToSomeFile}"/>
“PathToSomeFile”是ViewModel中的一个字符串变量,应在两个方向上进行更新
我怎样才能做到这一点?我错过了什么
非常感谢 如果您只是错过了双向部分,可以使用:
<pathselector:PathSelector SelectedPath="{Binding PathToSomeFile, Mode=TwoWay}" />
更多信息请点击此处:
您应该将文本框文本绑定到自定义DP,该DP将自动更新其源属性
<TextBox HorizontalAlignment="Stretch" VerticalAlignment="Center"
x:Name="SelectedPathTxtBox"
Text="{Binding SelectedPath, RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=UserControl}}"/>
另外,您不需要处理LostFocus,因为文本默认值
UpdateSourceTrigger
是LostFocus
。它将在失去焦点时更新绑定属性SelectedPath
由于
SelectedPath
,默认的UpdateSourceTrigger
值是PropertyChanged
,每当属性发生变化时,它都会更新PathToSomeFile
。修改SelectedPathChanged
,如下所示:
private static void SelectedPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((PathSelector)d).SelectedPathTxtBox.Text = e.NewValue.ToString();
MessageBox.Show("Changed!");
}
PathToSomeFile
是字段还是属性?PathToSomeFile
是实现InotifyPropertyChange的ViewModel中的属性。默认情况下,我已在DPGreat的register方法中使用BindsTwoWayByDefault=true
设置此属性!这帮了我。。。谢谢!非常有用。。。这将改变现状。谢谢刚刚意识到我必须添加Mode=TwoWay
和UpdateSourceTrigger=PropertyChanged
两个方向都得到更新文本默认Mode
是TwoWay
。如果您想更新PropertyChanged上的源值,则需要使用updateSourceTracger=PropertyChanged
。但根据你的问题,我想你希望它是关于LostFocus的更新。无论如何,如果您希望它在PropertyChanged上更新,只需设置UpdateSourceTrigger=PropertyChanged
。通常情况下,我不知道默认值,并将它们设置为我知道该值的真实值。因为默认情况下,TwoWay
,所以它在没有设置模式的情况下工作。但是如果没有UpdateSourceTrigger
,则在使用浏览对话框设置路径时不会更新。(可能是因为我刚刚设置了文本属性!?)是的,米兰的答案是“真正的”解决方案(有效)。你的回答帮助我得到了一些“更干净”的代码。所以谢谢你们两位:)