WPF用户控件绑定

时间:2018-09-25 13:10:11

标签: c# wpf data-binding

背景知识:我试图围绕Windows Presentation Foundation的数据绑定进行研究。我了解其中的大部分内容(或至少我认为是的),但是尝试将数据从父级绑定到用户控件会令我感到困惑。还感觉互联网上的每个人对此都有不同的方法,这无济于事。

我当前正在创建一个小型控件来管理正在处理的文件,然后将其上传到服务。该控件现在很简单,仅显示文件名和路径。最终它将随着更多的复杂性而增长,所以我现在想把绑定放下来。

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

使用控件,其中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(混淆名称空间):

<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 File.Name, ElementName=UploadDataItem, FallbackValue='File Name'}" />
    <TextBlock FontSize="10" FontStyle="Italic" Foreground="Gray" Text="{Binding File.FullName, ElementName=UploadDataItem, FallbackValue='x:\\file\\path\\here'}" />

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

最后,后面的代码:

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

我希望该控件处理有关上传文件的所有内容;也就是说,将文件显示为待处理,正在处理时显示一个上传栏,并在完成时显示“最终结果”。

问题是..我在做什么,要绑定文件数据?

2 个答案:

答案 0 :(得分:0)

DataContext的{​​{1}}继承自其父项。因此,在UserControl中,您无需指定“文件”。 dataContext已经是选定的文件。

UserControl

答案 1 :(得分:0)

此标记要求您将名为<?php include your required libraries.. include_once("lib/xlsxwriter.class.php"); ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Download IDs</title> </head> <body> <?php $sqlsel = $_SESSION['rptQry']; $ressql = mysqli_query($sqlsel); $currentdt = date('Ymdhis'); $filename = $currentdt."_".$_SESSION['rptFileName']; $header = array( 'Header1'=>'integer', 'Header 2'=>'integer', 'Header 3'=>'string', 'Header 4' =>'string' ); $dataArray = array(); $writer = new XLSXWriter(); $writer->setAuthor('Adaptable Services'); $writer->writeSheetHeader('ExportedIDs', $header); while($res = mysqli_fetch_array($ressql)){ $writer->writeSheetRow('Sheet1',$res); } $writer->writeToFile('/var/www/html/tmpxls/'.$filename); echo '<script>location.href="www.example.com/tmpxls/'.$filename.'";</script>'; ?> </body> </html> 的{​​{3}}添加到File控件中:

ControlUploadDataItem

您还应该避免在控件的构造函数中设置<controls:ControlUploadDataItem File="{Binding}" /> 属性,因为这将阻止它从对象树的父元素继承DataContext

DataContext

您实际上并不需要this.DataContext = new UploadDataViewModel(); UploadDataViewModel属性属于控件,并绑定到控件FileFileInfo的源集合中的ListView。然后,ItemTemplate控件可以绑定其自己的ControlUploadDataItem依赖项属性的属性。