c# - DependencyProperty 绑定(bind)问题

标签 c# .net wpf mvvm-light

我创建了一个小的文件浏览器控件:

<UserControl x:Class="Test.UserControls.FileBrowserControl"
             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="44" d:DesignWidth="461" Name="Control">
    <Grid Margin="3">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <TextBox  Margin="3" Text="{Binding SelectedFile}" IsReadOnly="True" TextWrapping="Wrap" />
        <Button HorizontalAlignment="Right" Margin="3" Width="100" Content="Browse" Grid.Column="1" Command="{Binding BrowseCommand}" />
    </Grid>
</UserControl>

后面有以下代码:
public partial class FileBrowserControl : UserControl
{
    public ICommand BrowseCommand { get; set; }
    //The dependency property
    public static DependencyProperty SelectedFileProperty = DependencyProperty.Register("SelectedFile",
        typeof(string),typeof(FileBrowserControl), new PropertyMetadata(String.Empty));
    public string SelectedFile { get{ return (string)GetValue(SelectedFileProperty);}  set{ SetValue(SelectedFileProperty, value);}}
    //For my first test, this is a static string
    public string Filter { get; set; }

    public FileBrowserControl()
    {
        InitializeComponent();
        BrowseCommand = new RelayCommand(Browse);
        Control.DataContext = this;
    }
    private void Browse()
    {
        SaveFileDialog dialog = new SaveFileDialog();
        if (Filter != null)
        {
            dialog.Filter = Filter;
        }
        if (dialog.ShowDialog() == true)
        {
            SelectedFile = dialog.FileName;
        }
    }
}

我像这样使用它:
<userControls:FileBrowserControl SelectedFile="{Binding SelectedFile}" Filter="XSLT File (*.xsl)|*.xsl|All Files (*.*)|*.*"/>

(SelectedFile 是使用该控件的用户控件的 ViewModel 的属性)

当前的问题是,当我单击浏览时,用户控件中的文本框正在正确更新,但未设置 viewmodel 父控件的 SelectedFile 属性(未调用 set 属性)。

如果我将绑定(bind)的模式设置为双向,我得到了这个异常:
An unhandled exception of type 'System.StackOverflowException' occurred in Unknown Module.

那么我做错了什么?

最佳答案

主要问题是您在其构造函数中将 UserControl 的 DataContext 设置为自身:

DataContext = this;
您不应该这样做,因为它会破坏任何基于 DataContext 的绑定(bind),即破坏由 DataContext 属性的属性值继承提供的 View 模型实例
相反,您将更改 UserControl 的 XAML 中的绑定(bind),如下所示:
<TextBox Text="{Binding SelectedFile,
                RelativeSource={RelativeSource AncestorType=UserControl}}" />
    
现在,当您使用 UserControl 并编写类似的绑定(bind)时
<userControls:FileBrowserControl SelectedFile="{Binding SelectedFile}" />
SelectedFile 属性绑定(bind)到 View 模型中的 SelectedFile 属性,该属性应位于从父控件继承的 DataContext 中。

关于c# - DependencyProperty 绑定(bind)问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53755493/

相关文章:

c# - 如何使用 C# 查找一个月中的第三个星期五?

.net - 如何确定当前用户是否通过 .NET 中的终端服务登录?

c# - 如何在 dataGrid 中将 XML 中的数据排序为数字

c# - 使用 View 中的确认逻辑将命令绑定(bind)到 ViewModel

c# - 如何在删除/从字符串中修改字符串后获得所需的输出

c# - Entity Framework 性能缓慢

.net - 将 blob 存储在 SQL Server 中而不将 blob 读入内存

c# - 在cshtml页面中处理html标签和c#脚本

c# - 将 GridView 和一些文本下载到 ASP.NET 网站的 Excel 中

.net - 使用样式将控件包裹在边框中而不覆盖默认外观