带有浏览按钮的 WPF 路径文本框作为 UserControl

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21848621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:54:19  来源:igfitidea点击:

WPF Path TextBox with Browse Button as UserControl

c#wpfxamluser-controlsdependency-properties

提问by joerg

I am trying to make a very easy UserControl that has a path that you can type in a textbox or that you can find by clicking a browse button. I tried to do this with a dependency property but this doesn't work completely when binding to it.

我正在尝试制作一个非常简单的 UserControl,它的路径可以在文本框中键入,也可以通过单击浏览按钮找到。我试图用一个依赖属性来做到这一点,但在绑定到它时这并不完全有效。

Here my xaml:

这是我的 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>

And this is the codebehind:

这是代码隐藏:

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;
        }
    }
}

I want to use this UserControl like this later:

我想稍后像这样使用这个 UserControl:

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

"PathToSomeFile" is a string variable in the ViewModel that should be updated in both directions.

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

How can I achieve this? What am I missing?

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

Thanks a lot!

非常感谢!

采纳答案by Milan Raval

Modify SelectedPathChangedas below:

修改SelectedPathChanged如下:

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

    MessageBox.Show("Changed!");
}

回答by Rohit Vats

You should bind TextBox Text to your custom DPwhich will automatically update its source property.

您应该将 TextBox Text 绑定到您的自定义 DP,它会自动更新其源属性。

<TextBox HorizontalAlignment="Stretch" VerticalAlignment="Center"
         x:Name="SelectedPathTxtBox"
         Text="{Binding SelectedPath, RelativeSource={RelativeSource
                             Mode=FindAncestor, AncestorType=UserControl}}"/>


Also you don't need to handle LostFocus, since Text default UpdateSourceTriggervalue is LostFocus. It will update the binding property SelectedPathon lost focus.

也不需要处理 LostFocus,因为 Text 默认UpdateSourceTrigger值为LostFocus. 它将SelectedPath在失去焦点时更新绑定属性。

And since SelectedPath, default UpdateSourceTriggervalue is PropertyChanged, it will update PathToSomeFilewhenever property changes.

因为SelectedPath,默认UpdateSourceTrigger值是PropertyChanged,它会PathToSomeFile在属性改变时更新。

回答by Clement Dungler

If you just miss the both direction part, you can use:

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

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

More info here:

更多信息在这里:

MSDN Binding.Mode Property

MSDN Binding.Mode Property