Bit of background: I'm trying to wrap my head around Windows Presentation Foundation's data binding. I understand most of it (or at least, I think I do), but trying to bind to data from a parent to a user control keeps leaving me baffled. It also feels like everyone on the internet has a different approach to this, which does not help.
I'm currently creating a small control to manage a file being processed, then uploaded to a service. The control is simple right now, only displaying the filename and path. It will grow with more complexity eventually, so I want to get the bindings down now.
The issue is that despite UploadFiles being bound correctly and FullName working as intended (showing the FileInfo.FullName prop), I can't bind to the controls from the list view. Ideally, I'd like to bind to a ViewModel's File object, and go from there.
Using the control, where UploadFiles is an observable FileInfo list:
<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>
The UploadControl XAML (Namespace obfuscated):
<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>
Lastly, the code behind:
/// <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));
}
}
I'd like this control to handle everything about an uploaded file; that is, showing the file as pending, an upload bar when it's being worked on, and a "final result" when it completes.
Question is.. what am I doing wrong, to bind the file data?