WPF listView Getting Checked Item - c#

I have a list view, of which the first column is checkboxes to enable/disable the item which represents said row. The problem is, when I change the checkbox, it does not select the row. Thus, when inside my checkBox checked/unchecked event I do listView.SelectedItem, it is null and crashes. Is there any way to fix this behavior so the listView check will select the item? Or, if there is an equivalent CheckedItems property in WPF like there is in WinForms?
XAML:
<Grid>
<ListView x:Name="listView1" HorizontalAlignment="Left" Height="300" Margin="10,10,0,0" VerticalAlignment="Top" Width="375">
<ListView.View>
<GridView>
<GridViewColumn x:Name="StatusHeader" Header="Status" Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="5, 0" IsChecked="{Binding loaded}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn x:Name="NameHeader" Header="Name" Width="130" DisplayMemberBinding="{Binding name}" />
</GridView>
</ListView.View>
</ListView>
</Grid>
C#:
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
module v = (module)listView1.SelectedItem; // crash
_client.AddClientModule(v.path);
}
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
module v = (module)listView1.SelectedItem; // crash
_client.RemoveClientModule(v.name);
}

You can use the DataContext to access the ViewModel and manually select it (if it is desired).
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
var cb = (CheckBox)sender;
var v = (module)cb.DataContext;
_client.AddClientModule(v.path);
// Select manually
listView1.SelectedItem = v;
}
private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
{
var cb = (CheckBox)sender;
var v = (module)cb.DataContext;
_client.RemoveClientModule(v.path);
// Select manually
listView1.SelectedItem = v;
}

Related

find selected item in wpf xml

i have this xml code for show list view item in wpf :
<ListView FlowDirection="RightToLeft" Name="ListViewPost" HorizontalAlignment="Left" Height="504" Margin="1060,172,0,0" VerticalAlignment="Top" Width="304" Background="White" BorderBrush="Black">
<ListView.View >
<GridView>
<GridViewColumn Width="300" Header="عنوان" DisplayMemberBinding="{Binding Title}"/>
</GridView>
</ListView.View>
</ListView>
and using this code for show id in messsagebox :
private void listView1_MouseClick_1(object sender, RoutedEventArgs e)
{
int Id;
if (ListViewPost.SelectedIndex == -1) return;
Id = (int)ListViewPost.SelectedItems[0];
MessageBox.Show(Id.ToString());
}
now i put the break point in this function but it not enter in this . whats the problem ?
You could handle the SelectionChanged event:
private void ListViewPost_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
int Id;
if (ListViewPost.SelectedIndex == -1) return;
Id = (int)ListViewPost.SelectedItems[0];
MessageBox.Show(Id.ToString());
}
XAML:
<ListView FlowDirection="RightToLeft" Name="ListViewPost" HorizontalAlignment="Left" Height="504"
VerticalAlignment="Top" Width="304" Background="White" BorderBrush="Black"
SelectionChanged="ListViewPost_SelectionChanged_1">
<ListView.View >
<GridView>
<GridViewColumn Width="300" Header="عنوان" DisplayMemberBinding="{Binding Title}"/>
</GridView>
</ListView.View>
</ListView>
It will be raised whenever a new item is selected.

c# WPF Checkbox delete in Listview Grid

how do i delete specific row by select few checkbox and delete them same time?
and also update the XML file
im using sharp serialize
image
in the image you cant see how it should look like
Xaml:
<ListView Name="Trilogi" HorizontalAlignment="Left" Height="201" Margin="265,10,0,0" VerticalAlignment="Top" Width="240" SelectionChanged="ListView_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn Header="" Width="30">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="Chck" Checked="Chck_Checked" Command="{Binding Check}" Width="50" ></CheckBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="ID" Width="40" DisplayMemberBinding="{Binding Veh_Key}"/>
<GridViewColumn Header="Plate Number" Width="80" DisplayMemberBinding="{Binding Veh_Value}"/>
</GridView>
</ListView.View>
</ListView>
<Button Name="Del" Content="Delete" HorizontalAlignment="Left" Height="27" Margin="523,17,0,0" VerticalAlignment="Top" Width="102" Click="Button_Click"/>
the add is work fine
only the select items in the checkbox
cs:
private void Chck_Checked(object sender, RoutedEventArgs e)
{
foreach (var item in Trilogi.SelectedItem.ToString())
{
i
veh[item].Veh_Is_Checked = true;
MessageBox.Show(veh[item].Veh_Key.ToString());
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach(var item in Trilogi.Items)
{
veh.Remove(item as Car);
}
}
Sorry, I can't comment. Don't have enough rep to do. But the answer i will give will assume you use are adding directly to the listview.
I think what you need to do is to create first a List of items when they are checked:
List<yourclass> selectedItems = new List<yourclass>();
Then on your xaml, you can add as tag the object you are using for binding:
<CheckBox Name="Chck" Checked="Chck_Checked" Command="{Binding Check}" Width="50" tag="{Binding}"></CheckBox>
and then what you can do in your check event is to add or remove the items, depending on the value of the checkbox say:
private void Chck_Checked(object sender, RoutedEventArgs e)
{
CheckBox chk = (CheckBox)sender;
yourclass newVal = (yourclass)chk.Tag;
if (chk.IsChecked.HasValue && chk.IsChecked.Value)
{
selectedItems.Add(newVal);
}
else
{
selectedItems.Remove(newVal);
}
}
and now on your delete button code, you can loop on the list and remove them. And now you can use the list to then call your code for removing them on your xml as basis on what item to remove
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (var item in selectedItems)
{
Trilogi.Items.Remove(item);
}
callMethodToRemoveItemsToXML();
selectedItems.Clear();
}

Delete record using ListBox and Button

I need show all records from database in ListBox and add button in ListBox to delete that particular record from database using c# in wpf application.
I used... but not able to add Button in ListBox in front of record.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Button b = new Button();
b.Content = "myitem";
b.Click += new RoutedEventHandler(b_Click);
listboxEmployee.Items.Add(b);
}
void b_Click(object sender, RoutedEventArgs e)
{
//code
}
And XAML:
<ListView Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="4" Grid.RowSpan="4" Name="listboxEmployee" SelectionChanged="listboxEmployee_SelectionChanged">
<ListView.View>
<GridView>
<GridViewColumn>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Try this:
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button Name="btnDelete" Content="Delete" Click="BtnDelete_OnClick" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
And then:
private void BtnDelete_OnClick(object sender, RoutedEventArgs e)
{
var s = (((sender as Button).DataContext) as YourModel).Property;
//Write Delete code based on "s" value
}

WPF ListViewItem Drag and Drop onto TextBlock

I am writing a simple addressbook example application in WPF in which I have a listview that holds the contacts as User objects, but each item is represented with a TextBlock only showing the name.
What I want to achieve is that a user can drag the item onto a "group". Groups are presented on the left hand side of the window. It is a simple grid column with several TextBlock items.
My relevant codebehind:
/** Display Contact in the contact pane**/
private void lstItemContact_MouseDown(object sender, MouseButtonEventArgs e)
{
ListViewItem item = (ListViewItem)sender;
User selectedUser = (User) item.Content;
DragDrop.DoDragDrop(lstContacts, item, DragDropEffects.Move);
contactPane.Fullname = selectedUser.Name;
contactPane.Email = selectedUser.Mail;
}
private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
{
User dropped_user = (User)sender;
MessageBox.Show(dropped_user.Name);
}
And the XAML:
<ListView x:Name="lstContacts" Width="250" Grid.Row="1" Grid.Column="1">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
</GridView>
</ListView.View>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock x:Name="lstItemContact" FontWeight="Bold" FontSize="14" Text="{Binding Name}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="lstItemContact_MouseDown" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
<TextBlock AllowDrop="True" Drop="tbFavouritesDrop_Drop" Name="tbFavouritesDrop">
<Border CornerRadius="3" Background="OrangeRed" Height="7" Width="7" VerticalAlignment="Center" Margin="0 0 2 5"/>
<Label FontFamily="Segoe UI Light" FontSize="14" Padding="0">Favourites</Label>
</TextBlock>
Once I drag the Item onto the "Favourites" Group I get the following error:
Additional information: Unable to cast object of type 'System.Windows.Controls.TextBlock' to type 'AddressBook1.User'
I am not sure what the exact problem is? Is the problem, that my listview item is a textblock ? The item I am sending is a User Object, and that reaches tbFavouritesDrop_Drop as well.
EDIT 1:
I have changed my Drop event handler to:
private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
{
TextBlock item = (TextBlock)sender;
MessageBox.Show(item.Text);
}
No exception is thrown, however, the .Text property is empty.
Ok, I found a solution after going crazy from another thread: WPF Drag and Drop - Get original source info from DragEventArgs
Which leaves me with:
/** Display Contact in the contact pane**/
private void lstItemContact_MouseDown(object sender, MouseButtonEventArgs e)
{
ListViewItem item = (ListViewItem)sender;
User selectedUser = (User) item.Content;
contactPane.Fullname = selectedUser.Name;
contactPane.Email = selectedUser.Mail;
}
private void lstItemContact_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (e.Source != null)
{
User selectedItem = (User) lstContacts.SelectedItem;
DragDrop.DoDragDrop(lstContacts, selectedItem, DragDropEffects.Move);
}
}
}
private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
{
User selectedUser = e.Data.GetData("AddressBook1.User") as User;
MessageBox.Show(selectedUser.Name);
}
I hope that helps someone else. The point here was to use e.Data.GetData("AddressBook1.User") and not work with the sender.

GridView is Not Loading Data

I'm trying to load data into a GridView after a TextBlock from another GridView on the page has been tapped/clicked. The first GridView containing the list of TextBlocks loads correctly.
Here is my XAML code for both GridViews, my Bindings seem to be correct:
<GridView x:Name="CourseNoGridView" Margin="50,50,0,0" Grid.Row="1" VerticalAlignment="Top" Height="568" ItemsSource="{Binding Distinct_CourseNo}" SelectionMode="Single" Padding="0,0,0,10" HorizontalAlignment="Left" Width="525" SelectionChanged="CourseNoGridView_SelectionChanged">
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="White">
<TextBlock x:Name="CourseNoTextBlock" Text="{Binding CourseNo}" TextWrapping="NoWrap" FontSize="24" Width="200" Height="Auto" Padding="10" Tapped="CourseNoTextBlock_Tapped"/>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<GridView x:Name="SectionsGridView" Margin="580,50,0,0" Grid.Row="1" VerticalAlignment="Top" Height="568" ItemsSource="{Binding Clicked_CourseNo_Sections}" SelectionMode="Single" Padding="0,0,0,10" HorizontalAlignment="Left" Width="776" SelectionChanged="CourseNoGridView_SelectionChanged">
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="White">
<TextBlock x:Name="SectionTextBlock" Text="{Binding Get_Section}" TextWrapping="NoWrap" FontSize="24" Width="200" Height="Auto" Padding="10"/>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Here is my code for handling the clicking/tapping of an item in the first GridView:
private void CourseNoGridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
clickedSection = (Sections)e.AddedItems[0];
}
private void CourseNoTextBlock_Tapped(object sender, TappedRoutedEventArgs e)
{
this.Clicked_CourseNo_Sections = (from s in Roster_Sections
where s.CourseNo.Equals(clickedSection.CourseNo)
select s).ToList();
}
What you want to do is use an ObservableCollection and bind your your Grid View to this. Then in your "Tapped" event handler you clear the existing items from this collection and add the new items.
Something like this:
private readonly ObservableCollection<Sections> currentSections = new ObservableCollection<Sections>();
//This is what we bind to
public ObservableCollection<Sections> CurrentSections { get { return currentSections; } }
private void CourseNoGridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
clickedSection = (Sections)e.AddedItems[0];
}
private void CourseNoTextBlock_Tapped(object sender, TappedRoutedEventArgs e)
{
var courseSections = (from s in Roster_Sections
where s.CourseNo.Equals(clickedSection.CourseNo)
select s);
CurrentSections.Clear();
CurrentSections.AddRange(courseSections);
}
There's some documentation here:
http://msdn.microsoft.com/en-us/library/windows/apps/hh758320.aspx
It seems like adding the last line of code below fixed the problem.
private void CourseNoTextBlock_Tapped(object sender, TappedRoutedEventArgs e)
{
this.Clicked_CourseNo_Sections = (from s in Roster_Sections
where s.CourseNo.Equals(clickedSection.CourseNo)
select s).ToList();
SectionsGridView.ItemsSource = Clicked_CourseNo_Sections;
}

Categories

Resources