Been messing with this and can't seem to figure it out. It seems that the object sender is actually the ListView.. so even though if I figure out how to get the GridViewColumn as a child... I don't know how to distinguish which column was actually clicked?
<ListView x:Name="SingleTweet_ListView"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
MouseLeftButtonUp="SingleTweet_ListView_MouseLeftButtonUp"
Height="200" Margin="5,5,5,5" FontSize="12"
GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">
<ListView.View>
<GridView>
<GridViewColumn Header="Screen Name"
DisplayMemberBinding="{Binding Col1}" Width="112"/>
<GridViewColumn Header="Tweet"
DisplayMemberBinding="{Binding Col2}" Width="623"/>
</GridView>
</ListView.View>
</ListView>
void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
{
MessageBox.Show(((GridViewColumn)sender).Header.ToString());
//error cus the sender is actually the listview?
}
Sender will be ListView but you can check for OriginalSource which will be GridViewColumnHeader and can get column from it:
MessageBox.Show(((GridViewColumnHeader)e.OriginalSource).Column
.Header.ToString());
Related
I have a ListView that gets its values from a database, with the last column being buttons. What I am trying to do, is that when a button is clicked, the value of the Name in the same row will be returned.
Here's the relevant part of my XAML code:
<Grid Grid.ColumnSpan="2">
<ListView Name="PeopleList">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding [Name]}" />
<GridViewColumn Header="Phone" DisplayMemberBinding="{Binding [Phone]}" />
<GridViewColumn Header="Email" DisplayMemberBinding="{Binding [Email]}" />
<GridViewColumn Header="Actions" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Content=">" Click="ActionButton_Click"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
You should be able to get the exact Button that was clicked from the sender argument of the Click event. From there you should be able to get Button.DataContext, which would hold a reference to the item that is being displayed on that row.
It would be something like:
private void ActionButton_Click(object sender, EventArgs args)
{
var rowItem = (sender as Button).DataContext as People;
string name = rowItem.Name;
}
I'm making a WPF app, this app has a UserControl, which has a list view.
I tried to create a click event listener but i never got it to work right, and i havend find anything to solve it
I fill this list view items with an object like this:
List<AsesoriaClass> listaAsesorias = phpClass.getListaAsesoriasAsesor(asesor.ID);
foreach (var asesoria in listaAsesorias)
{
AsesoriaTable data = new AsesoriaTable(asesoria.AsesoriaID.ToString(), asesoria.ClienteNombre + " " + asesoria.ClienteApellidos, asesoria.FechaInicio.ToString(), asesoria.FechaFinal.ToString());
this.ListView.Items.Add(data);
}
And this is the XAML of the User Control:
<ListView x:Name="ListView">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding Path=Id}" Width="100"/>
<GridViewColumn Header="Cliente" DisplayMemberBinding="{Binding Path=Cliente}" Width="300"/>
<GridViewColumn Header="Inicio" DisplayMemberBinding="{Binding Path=Inicio}" Width="200"/>
<GridViewColumn Header="Final" DisplayMemberBinding="{Binding Path=Final}" Width="200"/>
</GridView>
</ListView.View>
</ListView>
I want to make a click listener so, when i click on an item something happens (to start i just want it to show a mesage box). how do i do this?
You can simply attach an Event Handler on SelectionChanged. Like this
ListView.SelectionChanged += LstOnSelectionChanged;
Where LstOnSelectionChanged is a method.
private void LstOnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show("Anything");
}
Hi all. When ListView item is double clicked it should display the corresponding data to text box, later i will write some code to update.
<p>Below is listview code on my xaml file</p>
<ListView Margin="534,233,10,18" Name="lvCus" MouseDoubleClick="ListViewItem_DoubleClick">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="TbCus">
<GridViewColumn Header="CusID" Width="40" DisplayMemberBinding="{Binding Path=CusID}" />
<GridViewColumn Header="fn" Width="120" DisplayMemberBinding="{Binding Path=fn}" />
<GridViewColumn Header="Lastname" Width="120" DisplayMemberBinding="{Binding Path=ln}" />
<GridViewColumn Header="Dob" Width="100" DisplayMemberBinding="{Binding Path=dob}" />
<GridViewColumn Header="Age" Width="60" DisplayMemberBinding="{Binding Path=age}" />
</GridView>
</ListView.View>
</ListView>
Below is code at backend.
private void ListViewItem_DoubleClick(object sender, RoutedEventArgs e)
{
ListViewItem item = lvCus.SelectedItems[0];
txtfn.Text = item.SubItems[1].Text;
txtln.Text = item.SubItems[2].Text;
txtdob.Text = item.SubItems[3].Text;
}
I see red underline near the code lvCus.SelectedItems[0] , Error: cannot implicitly convert type 'object' to 'System.Windows.Controls.ListViewItem'. An explict conversion exists (are you missing a cast?)
Any help would be appreciated. Thanks.
You need to cast to your type of object say Customer
Customer custObj = (Customer)lvCus.SelectedItems[0];
Then you can access the properties
txtfn.Text = custObj.fn;
txtln.Text = custObj.ln;
txtdob.Text = custObj.dob;
I can get events from everything under the headers, but I can't get an event from clicking the headers. Here's the XAML; notice the event is for the entire ListView, so it should activate when anything is clicked:
<ListView x:Name="myListView" MouseLeftButtonUp="myListView_MouseLeftButtonUp" Margin="10">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="File Path"
DisplayMemberBinding="{Binding Path=Path}" />
<GridViewColumn Header="File Size"
DisplayMemberBinding="{Binding Path=Size}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
And the event itself is very simple. Just show me that something has happened:
private void myListView_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
string output = sender.ToString();
MessageBox.Show(output);
}
Clicking anywhere under the headers responds perfectly:
"System.Windows.Controls.ListView Items.Count:0"
Clicking the "File Path" header does nothing. Clicking the "File Size" header does nothing.
MSDN says:
https://msdn.microsoft.com/en-us/library/vstudio/ms745786(v=vs.100).aspx
<ListView x:Name='lv' Height="150" HorizontalAlignment="Center" VerticalAlignment="Center"
GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler">
Visual Studio says there's no such thing as GridViewColumnHeader, so none of the code on MSDN works.
That's how WPF UI events work by default. They bubble up. If somebody eats the message along the way (which is what button type controls do), the higher level controls won't get it. You can either use the Preview version of the event, or the cleaner way to do it:
AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(ListView_OnColumnClick));
<GridViewColumn Width="150" >
<GridViewColumn.Header>
<GridViewColumnHeader Click="GridViewColumnHeader_Click">click me</GridViewColumnHeader>
</GridViewColumn.Header>
</GridViewColumn>
Even if a bit late, but in XAML you can do something like:
<!-- ListView -->
<GridView AllowsColumnReorder="True">
<GridViewColumn Width="220">
<GridViewColumnHeader Content="{DynamicResource ResourceKey=explorer_column_name}" Command="{Binding Path=ISortBy}" CommandParameter="{x:Static enu:SortType.Name}"/>
<GridViewColumn.CellTemplate>
//...
</GridViewColumn.CellTemplate>
</GridViewColumn>
//..
</GridView>
AddHandler should be called on the ListView, like:
myListView.AddHandler(GridViewColumnHeader.ClickEvent, new RoutedEventHandler(myListView_OnColumnClick));
Then e.OriginalSource can be casted to GridViewColumnHeader in your myListView_OnColumnClick and you can identify your column.
Something like this:
public class EffectViewModel
{
public string Name ...
ObservableCollection<KeyValuePair<int,object>> settings
public ObservableCollection<KeyValuePair<int,object>> Settings
{
get {return this.settings;}
set
{
this.settings = value;
this.RaisePropertyChanged ( "Settings" );
}
}
}
Right now I am trying to bind it like this:
EffectWindowViewModel.Effects is of type ObservableCollection<EffectViewModel>.
<ListView Width="1000"
Height="600"
ItemsSource="{Binding EffectWindowViewModel.Effects}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Key}"
Header="Name" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Value}"
Header="Value" />
</GridView>
</ListView.View>
</ListView>
But I don't know how to specify .Settings property.
Any ideas?
your actual binding will not work cause EffectViewModel has no key and Value Property. i really dont know what your listview should display. if you want a list of EffectViewModels then the Itemssource is right. if you want further for each EffectViewModel to display the settings. then you need somekind of itemsscontrol with Itemssource={Binding Settings}. this itemsscontrol of course will need a itemsstemplate with your Key and Value.
i have no VS here atm, but your GridViewColumn needs a kind of CellTemplate. and this template should consist of a itemscontrol. because you have 2collections!
this code is probably not right but should take you in the right direction
<ListView Width="1000"
Height="600"
ItemsSource="{Binding EffectWindowViewModel.Effects}">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Settings}">
<GridViewColumn.CellTemplate>
<DataTemplatex:Key="myCell4Settings">
<ListView ItemsSource="{Binding.}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Key}"
Header="Name" />
<GridViewColumn Width="Auto"
DisplayMemberBinding="{Binding Value}"
Header="Value" />
</GridView>
</ListView.View>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</ListView>
</DataTemplate>
</GridView>
</ListView.View>
btw you could also use 2 lists independent. one parent Combobox or listbox (x:Name=parent) with itemssource=EffectWindowViewModel.Effects and a second ListView like you have, with the itemssource binding:
ItemsSource="{Binding ElementName=parent, Path=SelectedItem.Settings}"
You could try:
ItemsSource="{Binding ElementName=Settings, Path=EffectWindowViewModel.Effects}"