I have this fileholder marked as 2. on the image. When I click on Upload PDF I want to create a new exactly the same looking fileholder from it's existing xaml after I have added a new file.
What im trying to ask is how can I access the xaml so that this would be possible?
The XAML:
<StackPanel Orientation="Horizontal">
<Border Width="192" x:Name="Stack">
<StackPanel x:Name="FileContentHolder">
<Border
Width="110"
Height="105"
HorizontalAlignment="Center"
Background="#844eff"
CornerRadius="10">
<Button
x:Name="OpenPDF"
Width="45"
Margin="0,75,0,15"
HorizontalAlignment="Center"
Background="White"
Click="OpenFile">
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5" />
</Style>
</Button.Resources>
<TextBlock
HorizontalAlignment="Center"
FontSize="9"
Foreground="#3b3939"
Text="Open" />
</Button>
</Border>
<TextBlock
x:Name="FileNameHolder"
Margin="0,5,0,0"
HorizontalAlignment="Center"
FontFamily="/Fonts/#TiroGurmukhi"
FontSize="12"
Foreground="White"
Text="FileName" />
</StackPanel>
</Border>
</StackPanel>
The existing logic:
public void UploadFileToLibrary(object sender, RoutedEventArgs e)
{
bool fileHasBeenAdded = false;
Microsoft.Win32.OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "pdf files (*.pdf)|*.pdf|All files (*.*)|*.*";
bool? response = openFileDialog.ShowDialog();
if (response == true)
{
string filepath = openFileDialog.FileName;
string filename = Path.GetFileNameWithoutExtension(filepath);
FileNameHolder.Text = filename;
globalFilepath = filepath;
}
fileHasBeenAdded = true;
if (fileHasBeenAdded)
{
// Save the added file locally
// System.Diagnostics.Debug.WriteLine("File has been added locally");
}
}
CodePudding user response:
You should define the repeating layout elements as DataTemplate
and then show it using a ListBox
. The items of the ListBox
are the filenames.
You can redefine the ListBox.ItemsPanel
to configure it to display the items horizontally.
MainWindow.xaml
<Window>
<ListBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=UploadedFiles}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border Width="192"
x:Name="Stack">
<StackPanel x:Name="FileContentHolder">
<Border Width="110"
Height="105"
HorizontalAlignment="Center"
Background="#844eff"
CornerRadius="10">
<Button x:Name="OpenPDF"
Width="45"
Margin="0,75,0,15"
HorizontalAlignment="Center"
Background="White"
Click="OpenFile">
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius"
Value="5" />
</Style>
</Button.Resources>
<TextBlock HorizontalAlignment="Center"
FontSize="9"
Foreground="#3b3939"
Text="Open" />
</Button>
</Border>
<TextBlock x:Name="FileNameHolder"
Margin="0,5,0,0"
HorizontalAlignment="Center"
FontFamily="/Fonts/#TiroGurmukhi"
FontSize="12"
Foreground="White"
Text="{Binding}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
MainWindow.xaml.cs
// The binding source for the ListView
public ObservableCollection<string> UploadedFiles
{
get => (ObservableCollection<string>)GetValue(UploadedFilesProperty);
set => SetValue(UploadedFilesProperty, value);
}
public static readonly DependencyProperty UploadedFilesProperty = DependencyProperty.Register(
"UploadedFiles",
typeof(ObservableCollection<string>),
typeof(MainWindow),
new PropertyMetadata(default));
public MainWindow()
{
InitializeComponent();
this.UploadedFiles = new ObservableCollection<string>();
// TODO::If necessary initialize UploadedFiles collection with filenames
}
public void UploadFileToLibrary(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "pdf files (*.pdf)|*.pdf|All files (*.*)|*.*";
bool? response = openFileDialog.ShowDialog();
if (response == true)
{
string filepath = openFileDialog.FileName;
string filename = Path.GetFileNameWithoutExtension(filepath);
// Display a new "fileholder" box in the view
this.UploadedFiles.Add(filename);
...
}
...
}
See
- Microsoft Docs: Data Templating Overview
- Microsoft Docs: Dependency properties overview
- Microsoft Docs: Data binding overview (WPF .NET)
CodePudding user response:
You could clone the StackPanel
using the System.Windows.Markup.XamlWriter
class:
string xaml = XamlWriter.Save(FileContentHolder);
StackPanel newStackPanel = (StackPanel)XamlReader.Parse(xaml);
Button openPdf = newStackPanel.FindName("OpenPDF") as Button;
if (openPdf != null)
{
openPdf.Click = OpenFile;
}
root.Children.Add(newStackPanel);
Note that you'll have to programmatically re-attach any event handlers: