wpf File Explorer change name of file inside ListView - wpf

Hello I have a model called FileDirectoryModel and it contains:
public class FileDirectoryModel
{
public string imgPath { get; set; }
public string DirPath { get; set; }
public string FileName { get; set; }
public string size { get; set; }
public string FileType { get; set; }
public DateTime Modifed { get; set; }
public string FullName { get; set; }
}
I also have a ListView :
<ListView x:Name="lstExplorer"
Background="White"
ItemsSource="{Binding DirectoryCollection}"
SelectedItem="{Binding SelectedModel}"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding FileExplorerClickCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.View>
<GridView>
<GridViewColumn Header="Name"
Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding imgPath}"
Height="20"
Width="20"
Stretch="Fill"/>
<TextBlock x:Name="explorerText"
Text="{Binding FileName}">
</TextBlock>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="50">
<GridViewColumnHeader>
<TextBlock Text="Size" />
</GridViewColumnHeader>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding size}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="100">
<GridViewColumnHeader>
<TextBlock Text="Type" />
</GridViewColumnHeader>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding FileType}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="100">
<GridViewColumnHeader>
<TextBlock Text="Modifed" />
</GridViewColumnHeader>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding Modifed}" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
and DirectoryCollection is :
private ObservableCollection<FileDirectoryModel> _DirectoryCollection;
public ObservableCollection<FileDirectoryModel> DirectoryCollection
{
get { return _DirectoryCollection; }
set
{
if (_DirectoryCollection != value)
{
_DirectoryCollection = value;
OnPropertyChanged();
}
}
}
There is a dubbleclick command that will open the file that is selected but I'm having a hard time trying yo figure out how to allow someone to change the name of the selected item.
Please note that I saw File ListView, Change name which doesn't apply because they are telling how to change the file name not how to have xaml allow the change.

You will need to setup a CommandParameter to pass get the name of the double clicked item.
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding FileExplorerClickCommand}"
CommandParameter="{Binding}/>
</i:EventTrigger>
The FileDirectoryModel item that was double clicked will get passed to the FileExplorerClickCommand method (you will need to change the method params. You can then perform whatever you need on that item.

Related

get selected item ID from list view when click a button on the list view

Below is xaml and ListView:
<ListView x:Name="lvImages" ItemsSource="{Binding Path=resimGuncelle}" SelectedItem="{Binding Path=ID}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Name="MyImage" Source="{Binding RESIM_YOLU}" Width="120" Height="110" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding FileName}" x:Name="txtx" x:Uid="dd" />
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Style="{StaticResource DaireButtonResimSil}" x:Name="btndil" Click="btndil_Click"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I want to get Selected item ID , something like this:
private void btndil_Click(object sender, RoutedEventArgs e)
{
var selectedImageId = ((ResimGuncelleme)lvImages.SelectedItem).ID;
}
If i am getting this right, you have an ItemDataModel for your ListView items, and it has an Id property. Each time you click on a row predefined button you want to get that row item's Id property (without selecting the row, otherwise you could simply check the ListView's SelectedItem property).
Assuming your ItemModel looks something like this:
public class ItemModel
{
public string Id { get; set; }
public BitmapSource ResimYolu { get; set; }
public string FileName { get; set; }
}
In your xaml you could pass the item where the button was clicked in the Button's Tag using a RelativeSource binding:
<Grid>
<ListView x:Name="lvImages" ItemsSource="{Binding Path=ResimGuncelle}" SelectedItem="{Binding Path=Id}">
<ListView.View>
<GridView>
<GridViewColumn Header="Image">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Name="MyImage" Source="{Binding ResimYolu}" Width="120" Height="110" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Title" DisplayMemberBinding="{Binding FileName}" x:Name="txtx" x:Uid="dd" />
<GridViewColumn Header="Button">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button x:Name="btndil" Tag="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}}" Content="Button" Click="btndil_Click" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
And you can get that item's id from your button's click handler:
private void btndil_Click(object sender, RoutedEventArgs e)
{
var item=((sender as Button)?.Tag as ListViewItem)?.DataContext;
var itemId = (item as ItemModel)?.Id;
}
Ps: this isn't a very clean way to do that!

Multiline WPF ListViewItem

I have a ListView that I need to populate with some text data.
Currently my ListViewItem look this way (2 columns):
Name Number of files Files finished
XAML:
<ListView.View>
<GridView>
</GridView>
</ListView.View>
Here i have all my GridViewColumnHeader and my Binding data for example Name property:
<!-- file name column -->
<GridViewColumn>
<GridViewColumnHeader Content="File name" />
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
<GridViewColumn>
What i want to do now is to see my Name in first line and NumberOfFiles and FilesFinished in second line:
So after quick search i found this solution.
So i add this:
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Text="{Binding Name}" />
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="{Binding NumberOfFiles}" />
<TextBlock Text="{Binding FilesFinished}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
So after add my files into my ListView i cannot see any file, so i try to remove my ListView.View and still the files missing.
What i dong wrong ?
It's look fine. I just add listview name.
<Grid>
<ListView Name="ListViewFiles">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="Authors">
<GridViewColumn Header="File name" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="NumberOfFiles" Width="120" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding NumberOfFiles}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Code Sample. Maybe you forget ListViewFiles.ItemsSource = items;
public MainWindow()
{
InitializeComponent();
List<File> items = new List<File>();
items.Add(new File() { Name = "File One", NumberOfFiles = 2, Filesfished = "Yes" });
items.Add(new File() { Name = "File Two", NumberOfFiles = 2, Filesfished = "No" });
ListViewFiles.ItemsSource = items;
}
public class File
{
public string Name { get; set; }
public int NumberOfFiles { get; set; }
public string Filesfished { get; set; }
}

ListView SelectedItem does not get sychronized

I have following ListView and using MVVM Light
<ListView ItemsSource="{Binding Combinations, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding Combination, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
Style="{StaticResource UserValueStyle}" SelectionMode="Single"
IsSynchronizedWithCurrentItem="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollBarVisibility="Disabled" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Text}" FontSize="20" Height="80" Width="100" FontWeight="Bold"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.OnUserValuePressed}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The property:
public SapInspectionUserValue Combination
{
get
{
return _combination;
}
set
{
_combination = value;
RaisePropertyChanged();
}
}
The class property:
public class SapInspectionUserValue
{
public string Combination { get; set; }
public string Value { get; set; }
public string Text { get; set; }
}
My problem is, when I select an item(in my case, press the button) the SelectedItem does not get synchronized and I do not know why. Whats is wrong?

Multiple levels of binding in WPF ItemsControl

How can i bind multiple levels of data in same time like List of chapters and under each chapter list of pages.
The class structure and xaml i used is shown here
public class ContentsPage
{
public string cname{ get; set; }
public string label { get; set; }
}
public class Chapter
{
public string name { get; set; }
public string id { get; set; }
public List<ContentsPage> pages { get; set; }
}
public class Model
{
public List<Chapter> chapters { get; set; }
}
<ItemsControl x:Name="TopLevelListBox" ItemsSource="{Binding}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander ExpandDirection="Down" Width="175">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=name}" Margin="0,0,5,0"/>
</StackPanel>
</Expander.Header>
<ListBox x:Name="SubListBox" ItemsSource="{Binding Path=enrichments}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=cname}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
For binding i used the code
Model data = new Model(); //load data
TopLevelListBox.DataContext = data.chapters;
Only my expander headers are filled with result. What i need to do fill the pages inside the expander ? Any ideas or samples link for doing the same
Your ItemsControl Item template should change a bit. Instead of setting the ListBox as Content of Expander, set it as Content Template.
<Expander ExpandDirection="Down"
Width="175" Content="{Binding}">
<Expander.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=name}"
Margin="0,0,5,0" />
</StackPanel>
</Expander.Header>
<Expander.ContentTemplate>
<DataTemplate>
<ListBox x:Name="SubListBox"
ItemsSource="{Binding Path=enrichments}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=cname}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
And make sure you have sub items to show in ListBox.

DataTemplateSelector won´t get used

To switch between two ItemTemplates in my ListView based on the current Item type, I implemented a DataTemplateSelector. I added it via Binding to the ListView. But if I set a breakpoint, it never gets called. I tried everything, nothing works.
public class ListViewTemplateSelector : DataTemplateSelector
{
public DataTemplate SectionTemplate { get; set; }
public DataTemplate EntryTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is Section)
{
return SectionTemplate;
}
if (item is Entry)
{
return EntryTemplate;
}
return base.SelectTemplate(item, container);
}
}
XAML:
<ListView DataContext="{Binding ElementName=This}" x:Name="list" Margin="200,25,0,0" ItemsSource="{Binding CurrentSelection}" ItemTemplateSelector="{StaticResource TemplateSelector}">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}" Width="100" />
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Value}" Width="300" />
</GridView>
</ListView.View>
</ListView>
<DataTemplate x:Key="sectionTemplate">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Source="\Icons\blue-folder.png" />
<TextBlock Text="{Binding ID}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="entryTemplate">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Source="\Icons\ui-text-field-medium.png" />
<TextBlock Text="{Binding ID}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
<sdk:ListViewTemplateSelector x:Key="TemplateSelector" SectionTemplate="{StaticResource sectionTemplate}" EntryTemplate="{StaticResource entryTemplate}" />
Has anybody an idea how to fix that?
Thanks R
From GridView Overview > GridView Layout and Style > Defining and Styling Columns in a GridView:
When defining the data field to display in a GridViewColumn, use the
DisplayMemberBinding, CellTemplate, or CellTemplateSelector
properties. The DisplayMemberBinding property takes precedence over
either of the template properties.
Hence you would have to remove the DisplayMemberBinding from your GridViewColumns and set the CellTemplateSelector instead of the ListView's ItemTemplateSelector:
<GridView>
<GridViewColumn Header="ID" Width="100"
CellTemplateSelector="{StaticResource TemplateSelector}"/>
<GridViewColumn Header="Value" Width="300"
DisplayMemberBinding="{Binding Value}"/>
</GridView>

Resources