WPF路径TextBox,浏览按钮为UserControl

时间:2014-02-18 08:59:56

标签: 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="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;
        }
    }
}

我想稍后使用此UserControl:

<pathselector:PathSelector 
     SelectedPath="{Binding PathToSomeFile}"/>

“PathToSomeFile”是ViewModel中的一个字符串变量,应该在两个方向上进行更新。

我怎样才能做到这一点?我错过了什么?

非常感谢!

3 个答案:

答案 0 :(得分:2)

修改SelectedPathChanged,如下所示:

private static void SelectedPathChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ((PathSelector)d).SelectedPathTxtBox.Text = e.NewValue.ToString();

    MessageBox.Show("Changed!");
}

答案 1 :(得分:1)

您应将TextBox文本绑定到自定义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

答案 2 :(得分:0)

如果您错过了双向部分,可以使用:

<pathselector:PathSelector SelectedPath="{Binding PathToSomeFile, Mode=TwoWay}" />

更多信息:

MSDN Binding.Mode Property