C# WPF用户控件绑定

C# WPF用户控件绑定,c#,wpf,data-binding,C#,Wpf,Data Binding,背景知识:我正试图了解Windows Presentation Foundation的数据绑定。我理解其中的大部分(或者至少,我认为我理解),但试图将数据从父控件绑定到用户控件却让我感到困惑。这也让人觉得互联网上的每个人对此都有不同的处理方式,但这并没有帮助 我目前正在创建一个小控件来管理正在处理的文件,然后将其上载到服务。控件现在很简单,只显示文件名和路径。它最终会变得更加复杂,所以我想现在就开始绑定 问题是,尽管上传的文件已正确绑定,并且FullName按预期工作(显示FileInfo.Fu

背景知识:我正试图了解Windows Presentation Foundation的数据绑定。我理解其中的大部分(或者至少,我认为我理解),但试图将数据从父控件绑定到用户控件却让我感到困惑。这也让人觉得互联网上的每个人对此都有不同的处理方式,但这并没有帮助

我目前正在创建一个小控件来管理正在处理的文件,然后将其上载到服务。控件现在很简单,只显示文件名和路径。它最终会变得更加复杂,所以我想现在就开始绑定

问题是,尽管上传的文件已正确绑定,并且FullName按预期工作(显示FileInfo.FullName属性),但我无法从列表视图绑定到控件。理想情况下,我希望绑定到ViewModel的文件对象,然后从那里开始

使用控件,其中UploadFiles是可观察的FileInfo列表:

<ScrollViewer VerticalScrollBarVisibility="Auto">
        <ListView ItemsSource="{Binding UploadFiles}" Margin="5">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding FullName}" />
                        <controls:ControlUploadDataItem File="{Binding}" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </ScrollViewer>

UploadControl XAML(名称空间模糊):


最后,隐藏的代码:

/// <summary>
/// Interaction logic for UploadItem.xaml
/// </summary>
public partial class ControlUploadDataItem : UserControl
{

    public ControlUploadDataItem()
    {
        InitializeComponent();
        this.DataContext = new UploadDataViewModel();            
    }
}

internal class UploadDataViewModel: ViewModelBase
{

    private FileInfo _file;

    public FileInfo File
    {
        get { return _file; }

        set
        {
            _file = value;
            // Refresh(); ?
            OnPropChanged(nameof(File));
        }
    }
}

internal class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropChanged(string prop)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
}
//
///UploadItem.xaml的交互逻辑
/// 
公共部分类ControlUploadDataItem:UserControl
{
公共控制上载数据项()
{
初始化组件();
this.DataContext=new UploadDataViewModel();
}
}
内部类UploadDataViewModel:ViewModelBase
{
私有文件信息_文件;
公共文件信息文件
{
获取{return\u file;}
设置
{
_文件=值;
//刷新()?
OnPropChanged(文件名));
}
}
}
内部类ViewModelBase:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的void OnPropChanged(字符串prop)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(prop));
}
}
我想这个控件来处理所有关于上传文件的事情;也就是说,将文件显示为挂起,在处理时显示一个上载栏,在完成时显示“最终结果”


问题是。。绑定文件数据,我做错了什么?

用户控件的
DataContext
是从其父控件继承的。因此,在UserControl中,您不需要指定“File”。dataContext已经是所选文件

<UserControl x:Class="-----.Controls.ControlUploadDataItem"
     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:-----.Controls"
     mc:Ignorable="d" 
     d:DesignWidth="300"
     x:Name="UploadDataItem">    
<StackPanel Background="{StaticResource SecondaryColorBrush}" Margin="0, 0, 0, 10">
    <TextBlock FontSize="20" FontWeight="Bold" Foreground="{StaticResource PrimaryColorBrush}" Text="{Binding Name, FallbackValue='File Name'}" />
    <TextBlock FontSize="10" FontStyle="Italic" Foreground="Gray" Text="{Binding FullName, FallbackValue='x:\\file\\path\\here'}" />

    <!--<TextBlock FontWeight="Bold" Foreground="{StaticResource PrimaryColorBrush}" Text="{Binding Name, FallbackValue='File Name'}" />-->
</StackPanel>

此标记要求您向
ControlUploadDataItem
控件添加一个名为
的文件

<controls:ControlUploadDataItem File="{Binding}" />

这里不需要上传数据视图模型。
File
属性属于该控件,并绑定到该控件的
ItemTemplate
ListView
的源集合中的
FileInfo
ControlUploadDataItem
控件可以绑定自己的
文件的属性
依赖属性。

为什么要在
ControlUploadDataItem
类的构造函数中设置
DataContext
属性?不要这样做。在XAML中绑定到的文件属性在哪里?@mm8这是我的部分意思。一些人给出了这种工作的例子,其他人提到使用DependencyProperty。理想情况下,我只想在列表视图中使用
。您可以让
ControlUploadDataItem
继承DataContext并直接绑定到其中的Name和FullName。那么您不需要任何文件属性。如果确实需要它,则应在ControlUploadDataItem.xaml.cs中将其定义为dependendy属性。@mm8由于此控件演变为更复杂的内容,我需要创建一个上下文;继承上下文肯定是不够的。如果我添加了一个具有相同名称(文件)的依赖属性,那么它会自动工作吗?因此,请添加一个依赖属性,然后避免在构造函数中设置DataContext。那么您的绑定应该可以工作了。通过这样做,我是否能够在没有视图模型的情况下处理上载进度、控制状态(挂起、上载、完成)和类似信息?这就是促使我首先使用它的原因。如果您需要子视图模型,可以在父视图模型中创建一个,然后在ItemTemplate中设置控件的DataContext。当然,您也可以向控件添加几个依赖项属性。您可能需要阅读以下内容:将其更改为直接在控件类中使用DependencyProperty,效果会如预期的那样。将需要了解上下文(由于范围),但这解决了眼前的问题。
<controls:ControlUploadDataItem File="{Binding}" />
this.DataContext = new UploadDataViewModel();