UWP access controls in ListViewItem from colletion - c#

I have a ListView with two DataTemplate for items and headers.
Items from the ListView are binded to CollectionViewSource which looks like this:
<CollectionViewSource
x:Name="groupedItemsViewSource3"
Source="{Binding Groups2}"
IsSourceGrouped="true"
ItemsPath="Items"
d:Source="{Binding Groups, Source={d:DesignData Source=/DataModel/SampleData.json, Type=data:SampleDataSource}}"/>
I can manage to get ListViewItem but I cant get control of its child controls.
My ListView looks like this:
<ListView
Margin="0,40,0,0"
Width="580"
HorizontalAlignment="Right"
x:Name="itemGridView1"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource2}}"
SelectionMode="None"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick" Background="White">
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Background="LightGray" Width="2500" Height="25">
<Border HorizontalAlignment="Stretch" BorderThickness="0,0,0,1" BorderBrush="Black">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Time}" Margin="10,0,0,0" Width="50" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
<TextBlock Text="{Binding LiveTime}" Foreground="{Binding LiveTimeBGColor}" Margin="10,0,0,0" Width="40" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
<TextBlock Text="{Binding TeamOne}" Margin="0,0,10,0" HorizontalTextAlignment="Right" Width="150" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
<Border Background="DarkGray" Width="35" Margin="0,0,2,0" Padding="15,0,0,0">
<TextBlock Text="{Binding ScoreTeamOne}" Width="30" Foreground="White" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</Border>
<Border Background="DarkGray" Width="35" Padding="15,0,0,0" Margin="2,0,0,0">
<TextBlock Text="{Binding ScoreTeamTwo}" Foreground="White" Width="30" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</Border>
<TextBlock Text="{Binding TeamTwo}" Margin="10,0,0,0" HorizontalAlignment="Left" Width="150" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0,0,0,2" Width="2500" Background="{Binding HeaderLiveBGColor}">
<Button Foreground="{ThemeResource ApplicationHeaderForegroundThemeBrush}"
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextBlockButtonStyle}" Width="2500">
<StackPanel Orientation="Horizontal" Width="2500">
<TextBlock Text="{Binding LeagueTitle}" Margin="10,0,0,0" Width="441.9" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,20,0" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Any idea how can I check if the rights child control was clicked?
What I want to eventually achieve is the handle a click based on the controls of the ListViewItem clicked.

To get the clicked item from ListViewItem
If you add break points to debug your code, you could know there's a ClickedItem in ItemClickEventArgs class object. The ClickedItem should be that you want.
Another way is using TwoWay Binding on the SelectedItem.
Both the two ways are included in the following code sample:
<Page.Resources>
<CollectionViewSource
x:Name="groupedItemsViewSource3"
Source="{Binding Groups2}"
IsSourceGrouped="true"
ItemsPath="Items" />
</Page.Resources>
<Grid>
<ListView
Margin="0,40,0,0"
Width="580"
HorizontalAlignment="Right"
x:Name="itemGridView1"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource3}}"
SelectedItem="{Binding SelectedSong,Mode=TwoWay}"
SelectionMode="Single"
IsSwipeEnabled="false"
IsItemClickEnabled="True"
ItemClick="ItemGridView_ItemClick" Background="White">
<ListView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Background="LightGray" Width="2500" Height="25">
<Border HorizontalAlignment="Stretch" BorderThickness="0,0,0,1" BorderBrush="Black">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" Margin="10,0,0,0" Width="50" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0,0,0,2" Width="2500" Background="{Binding HeaderLiveBGColor}">
<Button Foreground="{ThemeResource ApplicationHeaderForegroundThemeBrush}"
AutomationProperties.Name="Group Title"
Style="{StaticResource TextBlockButtonStyle}" Width="2500">
<StackPanel Orientation="Horizontal" Width="2500">
<TextBlock Text="{Binding Key}" Margin="10,0,0,0" Width="441.9" Style="{StaticResource BodyTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,20,0" Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
public sealed partial class MainPage : Page
{
public ObservableCollection<SongGroup> Groups2 { get; set; }
private Song _SelectedSong;
public Song SelectedSong
{
get { return _SelectedSong; }
set
{
_SelectedSong = value;
}
}
public MainPage()
{
this.InitializeComponent();
Groups2 = GenerateData();
this.DataContext = this;
}
private ObservableCollection<SongGroup> GenerateData()
{
ObservableCollection<SongGroup> songGroups = new ObservableCollection<SongGroup>();
ObservableCollection<Song> songs = new ObservableCollection<Song>();
songs.Add(new Song() { Title = "Song1" });
songs.Add(new Song() { Title = "Song2" });
songGroups.Add(new SongGroup() { Key = "A", Items = songs });
ObservableCollection<Song> songs2 = new ObservableCollection<Song>();
songs2.Add(new Song() { Title = "Song2_1" });
songs2.Add(new Song() { Title = "Song2_2" });
songGroups.Add(new SongGroup() { Key = "B", Items = songs2 });
return songGroups;
}
private void ItemGridView_ItemClick(object sender, ItemClickEventArgs e)
{
var song = e.ClickedItem;
}
}
public class Song
{
public string Title { get; set; }
}
public class SongGroup
{
public string Key { get; set; }
public ObservableCollection<Song> Items { get; set; }
}

Related

Texbox value binding in WPF MVVM

I have sample XAML with TextBox code as:
XAML
<TextBox HorizontalAlignment="Stretch" VerticalAlignment="Center"
Text="{Binding Path=Remarks, UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0.5" Margin="0" Height="50" Background="Transparent" Foreground="White" />
<Button CommandParameter="{Binding ListExecActionId}"
Command="{Binding Source={StaticResource Locator}, Path=TaskPerformanceModel.ActivityAction_comment}"
Content="Save" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="3,0,0,0" Height="Auto" />
View Model:
public string Remarks
{
get { return _remarks; }
set
{
if (!string.Equals(_remarks, value))
{
_remarks = value;
RaisePropertyChanged("Remarks");
}
}
}
ActivityAction_coment as follows
public RelayCommand<object> ActivityAction_comment
{
get
{
if (_ActivityAction_comment == null)
{
_ActivityAction_comment = new RelayCommand<object>((ExecActionId) => ActivityComment(ExecActionId));
}
return _ActivityAction_comment;
}
}
private void ActivityComment(object _id)
{
try
{
using (DataContext objDataContext = new DataContext(DBConnection.ConnectionString))
{
ListExecutionAction tblListExec = objDataContext.ListExecutionActions.Single(p => p.Id == Convert.ToInt32(_id));
**tblListExec.Remarks = Remarks; // Not getting Remarks value from Textbox**
objDataContext.SubmitChanges();
}
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message, "TaskExecution:ActivityComment");
}
}
I am unable to get textbox (Remarks) value in view model. Always getting "".
can any one help me out please.
For more clarity I am updating view:
<ListView.View>
<GridViewColumn >
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding ActionDescription}" Foreground="White" FontSize="16"></TextBlock>
<ToggleButton Name="button">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<TextBlock>Remarks!!</TextBlock>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<Popup IsOpen="{Binding IsChecked, ElementName=button}" StaysOpen="False" Width="250" Height="100">
<StackPanel>
<TextBlock Background="LightBlue" Text="{Binding ActionDescription}"></TextBlock>
<TextBlock Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Center" Text="Comments:" Foreground="White" Background="Transparent" />
<TextBox HorizontalAlignment="Stretch" VerticalAlignment="Center"
Text="{Binding Path=Remarks, UpdateSourceTrigger=PropertyChanged}"
BorderThickness="0.5" Margin="0" Height="50"/>
<!--Text="{Binding Remarks, Mode=OneWayToSource}" Text="{Binding Path=Remarks, UpdateSourceTrigger=PropertyChanged}" DataContext="{Binding CollectionOfListQueue}" Background="Transparent" Foreground="White"-->
<Button CommandParameter="{Binding ListExecActionId}" Command="{Binding Source={StaticResource Locator}, Path=TaskPerformanceModel.ActivityAction_comment}" Content="Save" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="3,0,0,0" Height="Auto" />
<Button Content="Cancel" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="2,0,0,0" Height="Auto" />
<!--</Grid>-->
</StackPanel>
</Popup>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
Bind to ActivityAction_comment and Remarks properties of the view model:
<Button CommandParameter="{Binding ListExecActionId}"
Command="{Binding DataContext.ActivityAction_comment, RelativeSource={RelativeSource AncestorType=ListView}}"
Content="Save" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="3,0,0,0" Height="Auto" />
You need to the same for the Remarks binding
<TextBox Text="{Binding DataContext.Remarks, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType=ListView}}" ... />
You should then be able to get the value in the TextBox using the Remarks source property:
private void ActivityComment(object _id)
{
try
{
using (DataContext objDataContext = new DataContext(DBConnection.ConnectionString))
{
ListExecutionAction tblListExec = objDataContext.ListExecutionActions.Single(p => p.Id == Convert.ToInt32(_id));
string remarks = Remarks;
objDataContext.SubmitChanges();
}
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message, "TaskExecution:ActivityComment");
}
}

Listbox focus reset after selecting any item

I have a listbox in my WPF project filled by a MYSql database. When I scroll anywhere in the listbox and select an item, it immediately jumps to the first item and show the list from the beginning. I tried this solution but it gives me NullException. Here is the code:
private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var addedItems = e.AddedItems;
var selectedItem = (object)null;
if (addedItems.Count > 0)
{
selectedItem = addedItems[0];
}
object id = (((System.Data.DataRowView)selectedItem).Row.ItemArray[0]);
object name = (((System.Data.DataRowView)selectedItem).Row.ItemArray[1]);
object selectedType = (((System.Data.DataRowView)selectedItem).Row.ItemArray[2]);
}
and xaml part:
<ScrollViewer Width="582.5" Name="scrollViewer" HorizontalAlignment="Center" Background="Transparent" VerticalAlignment="Bottom" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Hidden" >
<ListBox x:Name="listBox" SelectionMode="Single" Visibility="Hidden" IsEnabled="False" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" HorizontalAlignment="Center" Background="Transparent" BorderBrush="Transparent" SelectionChanged="listBox_SelectionChanged" ItemsSource="{Binding Source={StaticResource TypeTable}}" HorizontalContentAlignment="Center" RenderTransformOrigin="0.5,0.5" Padding="0,0,0,90" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Name="stackPanel2" CanHorizontallyScroll="True" Orientation="Horizontal" HorizontalAlignment="Right" Height="180" Width="180" >
<Image Margin="3" Source="{Binding pic_path}" RenderOptions.BitmapScalingMode="Fant" RenderOptions.EdgeMode="Aliased"/>
<TextBox Margin="3" Text="{Binding name}" Visibility="Visible"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>

How to get CheckBox "Ticked" inside ListBox on run time

I am creating windows phone 8 application, I have checkbox inside listbox, how do I get checkbox "CHECKED" when I click on checkbox?
I tried my best but not getting the result?
see my code below:
<ListBox x:Name="listBox1" Width="429" Height="621" HorizontalAlignment="Left" Margin="21,43,0,59" VerticalAlignment="Top" ItemsSource="{Binding}" SelectedItem="{Binding}" SelectionChanged="listBox1_SelectionChanged" SelectionMode="Extended">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Vertical" Width="440">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" TextWrapping="Wrap" Foreground="Black" FontSize="22" Height="30" TextAlignment="Left" Width="Auto" FontWeight="SemiBold"/>
<TextBlock Text="{Binding}" TextWrapping="Wrap" Foreground="Black" FontSize="22" Margin="5" Height="30" TextAlignment="Left" Width="Auto" FontWeight="SemiBold"/>
</StackPanel>
<StackPanel>
<TextBlock Text="Favorite" TextWrapping="Wrap" Foreground="Black" FontSize="22" Height="30" FontWeight="SemiBold" Margin="344,-35,9,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" TextWrapping="Wrap" Foreground="Black" FontSize="22" Height="Auto" Width="Auto" TextAlignment="Left" FontWeight="SemiBold"/>
</StackPanel>
<CheckBox x:Name="CheckBox1" Height="72" Foreground="Black" IsChecked="False" Margin="353,-40,28,0" BorderBrush="Black" Loaded="CheckBox1_Loaded" Checked="CheckBox1_Checked" Unchecked="CheckBox1_Unchecked"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here is my code behind file:
private void CheckBox1_Checked(object sender, RoutedEventArgs e)
{
CheckBox cb = (CheckBox)sender;
cb.IsChecked = true;
}
I tried this on emulator in my listbox and it works fine. The textboxes checked and unchecked without any problem.
<ListBox.BorderBrush>
<SolidColorBrush />
</ListBox.BorderBrush>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="0,1,0,0" Width="600" Padding="0">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<Image Stretch="UniformToFill" Source="{Binding Image}" Width="130" Height="130" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image.Clip>
<RectangleGeometry RadiusX="15" RadiusY="15" Rect="0,0,130,130" />
</Image.Clip>
</Image>
<--CheckBox x:Name="CheckBox1" Height="72" Foreground="Black" IsChecked="False" BorderBrush="Black"/-->
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I got the solution:
private void CheckBox1_Checked(object sender, RoutedEventArgs e)
{
CONTACTS data = (sender as CheckBox).DataContext as CONTACTS;
string contactId = data.contactId;
string isFav = data.isFavourite.ToString();
}
Here is the answer:
private void CheckBox1_Checked(object sender, RoutedEventArgs e)
{
CLASS_NAME item = (sender as CheckBox).DataContext as CLASS_NAME;
string id = item.Id;
string name = item.Name;
}

longListSelector get index

I have longListSelector:
<DataTemplate x:Key="AddrBookItemTemplate" >
<StackPanel VerticalAlignment="Top">
<Grid Background="#3FCDCDCD" Margin="3,3,3,3">
<Image Source ="{Binding UrlImage}" Height="100" Width="100" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,0" Stretch="Fill"/>
<TextBlock Text="{Binding Title}" TextWrapping="Wrap" Margin="110,0,0,0" Foreground="Black" FontFamily="Portable User Interface"/>
</Grid>
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<phone:LongListSelector
x:Name="AddrBook"
Background="Transparent"
ItemTemplate="{StaticResource AddrBookItemTemplate}"
IsGroupingEnabled="true"
HideEmptyGroups ="true"
SelectionChanged="AddrBook_SelectionChanged"
/>
Preview - name of my class
How can i get index of PressedItem?
What should i write here -
private void AddrBook_SelectionChanged(object sender, SelectionChangedEventArgs e)
{ }
you should write
var longlistselector = (sender as LongListSelector);
int index = longlistselector.DataSource.IndexOf(longlistselector.SelectedItem);

Binding ObservableCollection of List

In my Windows Phone application I have a listBox with ContentItems binding :
private ObservableCollection<ContentItemViewModel> _contentItems;
public ObservableCollection<ContentItemViewModel> ContentItems
{
get { return _contentItems; }
}
<ListBox x:Name="ContentListBox" Margin="0,117,12,0" VirtualizingStackPanel.VirtualizationMode="Standard" Logic1:TiltEffect.IsTiltEnabled="True" ItemsSource="{Binding ContentItems}" Tap="ContentListBox_Tap" MinHeight="656" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="vertical" >
<Grid Height="{Binding ItemHeight}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" x:Name="itemIco1" Width="Auto" Height="Auto" HorizontalAlignment="Left" Source="{Binding IconURL}" Stretch="Fill" CacheMode="BitmapCache" VerticalAlignment="Top" Margin="5,5,5,5" Visibility="Visible"/>
<ListBox IsHitTestVisible="False" Grid.Column="1" VerticalAlignment="Center" >
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
<TextBlock x:Name="ContentCategoryTitle" Height="70" Text="{Binding ContentTitle}" Width="460" Margin="5,34,0,0" TextTrimming="WordEllipsis" TextWrapping="NoWrap" FontSize="28" FontFamily="Segoe WP Semibold" Foreground="#FFF7F7F7" VerticalAlignment="Bottom" />
</ListBox>
</Grid>
<Rectangle Fill="#FF585858" Height="1" Margin="0,0,0,0" Width="460" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Is it possible to binding not an ObservableCollection<ContentItemViewModel>, but - ObservableCollection<List<ContentItemViewModel>> ?
Yes that is possible, if you have a collection of collections. Or why not this?
ObservableCollection<ObservableCollection<ContentItemViewModel>>
If you want your UI to be notified of collection changes to your sub collections.
Update
For example:
View Model
public ObservableCollection<ObservableCollection<ContentItemViewModel>> ContentItems
{
get { return _contentItems; }
set { _contentItems = value; // Notify of property change here, this allows you to change the ContentItems reference after view model construction }
}
public MyViewModel()
{
// Populate content items
this.ContentItems = new ObservableCollection
{
new ObservableCollection { new ContentItemViewModel() },
new ObservableCollection { new ContentItemViewModel(), new ContentItemViewModel() }
};
}
View
<ListBox ItemsSource="{Binding ContentItems}" ...>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding MyContentItemViewModelProperty}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>

Categories