I have a GridView where I'm storing the songs the user adds to a collection:
<GridView x:Name="MusicGridView" Margin="10" IsItemClickEnabled="True" ItemClick="Play_Song" Grid.Row="0" ItemsSource="{Binding Songs, ElementName=thisPage, Mode=OneWay}" SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<Grid Height="100" Width="100" RightTapped="Song_RightTapped">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Grid.RowSpan="2" Fill="#FF1F4E79"/>
<Image Source="{Binding Path=AlbumArt.Source}" Grid.Row="0" Height="40" Width="40" Margin="10,10,10,0"/>
<TextBlock Text="{Binding Title}" Foreground="White" VerticalAlignment="Bottom" HorizontalAlignment="Center" Grid.Row="1" Margin="5" TextWrapping="Wrap"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
When the Grid is right-tapped (I can't seem to set a RightTapped property for the actual item) I show a PopupMenu. However, the sender is the Grid itself, of course, and I can't find a way to get the actual GridViewItem without doing what seem like really weird workarounds. Getting the selected item of the GridView isn't an option, since selection isn't enabled on it. Is there an easy way to get the item as a GridViewItem?
If I understand your question correctly you want to get the binded object instead of the GridView.
If that's the case you could try this.
private void Song_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
Song song = (sender as Grid).DataContext as Song;
// Show PopupMenu
// ...
}
Related
I have a ListBox and its ItemsSource is linked with a ComboBox SelectedItem. Its template is associated with a DataTemplate. Everything is fine but how to access each TextBox inside ListBoxItems. I have 5 labels and 2 TextBoxes inside each ListItem. I want to access each and every TextBox and labels inside ListBoxItem. I need some idea how to access each TextBox inside each Item. For example, there is "wbprofileDesc" TextBox in first ListBoxItem. So I need to access this TextBox and write some functionality to it like keypress event. It need to work for each and every TextBox inside all the ListBoxItems individually. Assume there are 5 ListBoxItems. Also I need to fetch other controls also like wbselect(ComboBox), wbdepth, wbwidthvalue and etc. I am using MVVM model for this.
<Window.Resources>
<local:wbItemViewModel x:Key="wbItem"/>
<DataTemplate x:Key="wbObjectsDataTemplate">
<Grid Grid.ColumnSpan="1" Grid.RowSpan="1" Height="Auto" Width="642" Margin="0,0,0,-14">
<Grid HorizontalAlignment="Left" VerticalAlignment="Top" Width="697" Margin="10,0,0,0" Height="54" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="49*"/>
<ColumnDefinition Width="91*"/>
<ColumnDefinition Width="309*"/>
<ColumnDefinition Width="306*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition/>
<RowDefinition Height="auto" MinHeight="5"/>
</Grid.RowDefinitions>
<Label Content="{Binding WBName_lbl}" Margin="0,3,0,5" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"/>
<ComboBox x:Name="wbselect" Margin="5,0,10,1" Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="0">
<ComboBoxItem x:Name="wbstraight" IsSelected="True" Content="straight"/>
<ComboBoxItem x:Name="wbtapered" Content="tapered"/>
</ComboBox>
<!--KeyDown="{Binding Path=profileDesc}"-->
<!-- KeyDown="profileDesc_KeyDown" -->
<TextBox x:Name="wbprofileDesc" Margin="18,0,20,1" Grid.Column="2" Grid.Row="0" GotFocus="wbprofileDesc_GotFocus"/>
<TextBox x:Name="wbdepth" Text="{Binding ElementName=wbwidthvalue, Path=Content, Mode=OneWay}" Margin="10,0,73,1" Grid.Column="3" Grid.Row="0"/>
<Label x:Name="wbwidthvalue" Margin="10,0,190,5" Grid.Column="2" FontSize="8" Grid.Row="1"/>
<Label x:Name="wbthicknessvalue" Margin="118,0,82,5" FontSize="8" Grid.Row="1" Grid.Column="2"/>
<Label x:Name="wblengthvalue" Margin="208,0,0,5" FontSize="8" Grid.Row="1" Grid.Column="2"/>
<Label x:Name="wbnexwidthvalue" Margin="10,0,178,5" FontSize="8" Grid.Row="1" Grid.Column="3"/>
<Label x:Name="wbdepthvalue" Grid.Row="1" Grid.Column="3" FontSize="8" Margin="132,0,31,5"/>
<!--<Label x:Name="totalvalue" Margin="30,10,24,16" Grid.Row="3" Grid.Column="3"/>-->
</Grid>
</Grid>
</DataTemplate>
</Window.Resources>
<ListBox x:Name="wbListDataTemplate"
ItemsSource="{Binding wbVisibleItems}"
ItemTemplate="{DynamicResource wbObjectsDataTemplate}"
DataContext="{DynamicResource wbItem}"
Background="{x:Null}"
SelectedItem="{Binding wbSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsSynchronizedWithCurrentItem="True"
Canvas.Top="51" Height="222" Width="686"/>
Here is an example of you could find the controls in the DataTemplate inside the event handler:
private void wbprofileDesc_GotFocus(object sender, RoutedEventArgs e)
{
TextBox wbprofileDesc = sender as TextBox;
Grid parentGrid = wbprofileDesc.Parent as Grid;
ComboBox wbselect = parentGrid.Children.OfType<ComboBox>().FirstOrDefault(x => x.Name == "wbselect");
Label wbwidthvalue = parentGrid.Children.OfType<Label>().FirstOrDefault(x => x.Name == "wbwidthvalue");
}
So I have a ListView bound to a Client Object. The client properties are shown on some textbox next to the ListView. If I change the name (that is shown in the ListView), I can't select anything else unless I revert back the name.
The ListView SelectedItem always stays selected if I change the value in the Text Box and the Text Box all show the same values, even if I select another.
I tried clearing the selected item, the ItemsSource nothing will work. It must be something with the source and the bindings.
My Source is a ObservableDictionary that I found somewhere here, so maybe that is the issue. My Client Object is Also implementing INotifyPropertyChanged. I tried a lot of thing with Binding and etc. But whatever I try the text Box will stay like that even if I select something else as long has the value isn't the restored to it's Original Value I can't select anything else.
XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<ListView x:Name="listView" Grid.RowSpan="7" Grid.Row="1" Margin="5,0" SelectionMode="Single" IsSynchronizedWithCurrentItem="True">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ClientIDandName}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Text="ID" Grid.Row="1" Grid.Column="1"/>
<TextBox Text="{Binding SelectedItem.ClientID, ElementName=listView}" IsEnabled="False" Grid.Row="1" Grid.Column="2"/>
<TextBlock Text="Nom" Grid.Row="2" Grid.Column="1"/>
<TextBox Text="{Binding SelectedItem.ClientName, ElementName=listView}" Grid.Row="2" Grid.Column="2"/>
<TextBlock Text="Temps de Transit" Grid.Row="3" Grid.Column="1"/>
<TextBox Text="{Binding SelectedItem.TransitTime, ElementName=listView}" Grid.Row="3" Grid.Column="2"/>
<TextBlock Text="Nbr. de Jour Max" Grid.Row="4" Grid.Column="1"/>
<TextBox Text="{Binding SelectedItem.MaxShipDays, ElementName=listView}" Grid.Row="4" Grid.Column="2"/>
<TextBlock Text="Exclure" Grid.Row="5" Grid.Column="1"/>
<CheckBox IsChecked="{Binding SelectedItem.IsExcluded, ElementName=listView}" Grid.Row="5" Grid.Column="2" VerticalAlignment="Bottom"/>
<Button x:Name="btnSave" Content="Sauvegarder" Click="btnSave_Click" Grid.Row="7" Grid.Column="1" Grid.ColumnSpan="2" HorizontalAlignment="Center"/>
</Grid>
Code Behind
public partial class ClientConfig : UserControl
{
public ClientConfig()
{
InitializeComponent();
listView.ItemsSource = Client.LocalDB.Values.ToObservableCollection();
}
private void btnSave_Click(object sender, RoutedEventArgs e)
{
Client client = listView.SelectedItem as Client;
if (client != null)
{
client.Save();
}
}
}
I usually use the MVVM design pattern and keep my objects in a viewmodel, so you will have to modify the code accordingly.
I think that your problem is how you create your ObservableCollection in code. When you call ToObservableCollection(), it enumerates all of the values in Client.LocalDB.Values, but I don't think it will persist as an object like you expect it to - especially since it is local to the method that you are creating it in. The ListView continues to show data because nothing is telling it to change, but the ObservableCollection does not actually exist anymore. You will want to create an observable collection that is global to the whole class, and populate it instead.
This is untested code, but should get you close... in code behind:
private ObservableCollection<Whatever> _myCollection;
public ObservableCollection<Whatever> MyCollection
{
get
{
return _myCollection;
}
set
{
if (_myCollection != value)
{
_myCollection = value;
RaisePropertyChanged("MyCollection");
}
}
}
private Whatever _selectedWhatever;
public Whatever SelectedWhatever
{
get
{
return _selectedWhatever;
}
set
{
if (_selectedWhatever != value)
{
_selectedWhatever = value;
RaisePropertyChanged("SelectedWhatever");
}
}
}
public ClientConfig()
{
InitializeComponent();
foreach (Whatever whatevs in Client.LocalDB.Values.ToObservableCollection())
{
MyCollection.Add(whatevs); // populate the collection this way and it will persist
}
}
and in XAML:
<ListView x:Name="listView" Grid.RowSpan="7" Grid.Row="1" Margin="5,0" SelectionMode="Single" IsSynchronizedWithCurrentItem="True" ItemSource="{Binding MyCollection}" SelectedItem="{Binding SelectedWhatever}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ClientIDandName}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Notice that you have now bound the collection to a persistent variable that can be changed, and you have bound the selected item to a specific instance of that collection. Now you can bind your textboxes to the SelectedWhatever and changes made in one place should be reflected in the other place.
I have a <Checkbox/> in my <GridView.ItemTemplate>. How do I handle the <Checkbox/> as to the element in which it is?
For example, I want to delete item when checkbox checked.
I think should write here. But what?
private void CheckBox_Checked_1(object sender, RoutedEventArgs e)
{
}
Here's My XAML:
<GridView Margin="0,10,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
x:Name="GridColections"
IsItemClickEnabled="True"
SelectionMode="None"
ItemsSource="{x:Bind DS.AllRem, Mode=OneWay}"
ItemClick="GridColections_ItemClick" >
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:GetRem" >
<Grid Margin="-2,0,-6,0" BorderBrush="LightGray" BorderThickness="1" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<TextBlock TextTrimming="CharacterEllipsis" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="{x:Bind ReminderName}" Margin="5,5,0,0" FontSize="20"/>
<TextBlock TextTrimming="CharacterEllipsis" Grid.Column="0" Grid.Row="1" Width="600" TextWrapping="Wrap" Text="{x:Bind ReminderDescription}" Margin="5,5,0,0" FontSize="12"/>
<CheckBox Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Center" Checked="CheckBox_Checked_1"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The problem is that you almost certainly want to be able to use the DataContext in your click handler but you won't get that easily by just having a reference to the CheckBox which will be the sender argument in your callback. Normally what you would do here is create a Command on your item's view model and bind to that and any additional information that you would want to pass in you would pass in through the CheckBox's CommandParameter.
Once you do this you are now operating in your view model with a reference to whatever piece of information that you need through the command parameter (for instance you could set CommandParameter = "{Binding}" to pick up the entire data context which would be the item's view model and that would be accessible from your Command as an argument to it). You should be able to solve your issue this way.
I am using list view to display a list of items in a group. Here is how my list view looks like:
<ListView
x:Name="itemListView"
AutomationProperties.AutomationId="ItemListView"
AutomationProperties.Name="Items In Group"
TabIndex="1"
Grid.Row="1"
ItemsSource="{Binding Items}"
IsItemClickEnabled="True"
ItemClick="ItemView_ItemClick"
SelectionMode="None"
IsSwipeEnabled="false"
Margin="19,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Margin="0,-9.5,0,0" Width="79" Height="79">
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}" VerticalAlignment="Top"/>
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="14.5,0,0,0">
<TextBlock Text="{Binding Title}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
<TextBlock Text="{Binding Description}" Style="{ThemeResource ListViewItemContentTextBlockStyle}" Foreground="{ThemeResource PhoneMidBrush}" TextWrapping="WrapWholeWords"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I would like to add a logic that when a text block is selected, it should copy the entire text block to another hub page (favorite) and create a reference back to the source text block. Whenever the user clicks any text block, it should be copied to the existing list of favorite blocks on Favorite hub page. Also, the user should be able to select the block on the favorite and remove it from the favorite list.
Currently, my "ItemView_ItemClick event looks like below which get the Id of the selecte item in the list, but I don't know how to proceed to implement above logic.
private void ItemView_ItemClick(object sender, ItemClickEventArgs e)
{
var itemId = ((SampleDataItem)e.ClickedItem).UniqueId;
if (!Frame.Navigate(typeof(ItemPage), itemId))
{
var resourceLoader = ResourceLoader.GetForCurrentView("Resources");
throw new Exception(resourceLoader.GetString("NavigationFailedException`enter code here`Message"));
}
You can use IsolatedStorageSettings for local storage.
I have a page with a Pivot. It´s based on the Visual Studio Template.
<!--Pivot Control-->
<phone:Pivot SelectionChanged="evt_pivot_SelectionChanged">
<phone:Pivot.Title>
<StackPanel HorizontalAlignment="Center">
<!-- <TextBlock Text="MyApp" /> -->
<Image Stretch="None" HorizontalAlignment="Left" Margin="0" MinWidth="50" MaxHeight="50" Source="/mAppData/logo.png"/>
</StackPanel>
</phone:Pivot.Title>
<!--Pivot item one-->
<phone:PivotItem Header="Favoriten">
<!--Double line list with text wrapping-->
<phone:LongListSelector Margin="13,0,0,0" ItemsSource="{Binding Items}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,25">
<Grid VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" Text="FELIX ClubRestaurant (Berlin)" TextWrapping="NoWrap" Style="{StaticResource PhoneTextLargeStyle}" VerticalAlignment="Top" Margin="0,0,0,22" />
<Image Grid.Column="0" Width="110" Height="20" Source="/mAppData/stars-3.png" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="0"/>
<TextBlock Grid.Column="1" Text="10 min." TextWrapping="NoWrap" Margin="0" Style="{StaticResource PhoneTextSubtleStyle}" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
</Grid>
<Grid VerticalAlignment="Top" Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Width="100" Height="100" Source="http://img.myserver.net/news-teaser//p189j19861b36c5d1pp012i21grgd.gif"/>
<Image Grid.Column="1" Width="100" Height="100" Source="http://img.myserver.net/news-teaser//p187qrndfcj0la0f12clfkv10ec7.gif"/>
<Image Grid.Column="2" Width="100" Height="100" Source="http://img.myserver.net/news-teaser/005e5d03f058fa8f7bd95f6410dfc6d6.gif"/>
<Image Grid.Column="3" Width="100" Height="100" Source="http://img.myserver.net/news-teaser/3c05cbf76fba7ada5182b4426e55d96b.gif"/>
</Grid>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</phone:PivotItem>
<!--Pivot item two-->
<phone:PivotItem Header="Empfohlen">
</phone:PivotItem>
</phone:Pivot>
I added in CodeBehind the handling for the event SelectionChanged. That works fine. So I can capture by code, when user comes to the second PivotItem.
private async void evt_pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
int mPivotIndex = Convert.ToInt16(((Pivot)sender).SelectedIndex.ToString());
if (mPivotIndex == 1)
{
// HERE I WANT TO INSERT THE SOLUTION
}
}
Now comes my problem: When user navigates to seconds item, I want to:
request some data from an WebService (this in not the problem)
transform the data (this is not the problem) and
populate the data in a LongListSelector (THIS IS MY PROBLEM PART 1)
In case that an error occures, I want not to display the LongListSelector but a TextBox showing a message (THIS IS MY PROBLEM PART 2)
How can I get my 2 problems get working?
You will need to bind the text/content of your controls in the itemtemplate to the data collection fieldname
Text="{Binding Fieldname}"
http://msdn.microsoft.com/en-us/library/windowsphone/develop/jj207023(v=vs.105).aspx
In your error handling, set the visibility of the Longlistselector to Collapsed. Then you can show another control which displays the textbox
<StackPanel>
<LongListSelector x:Name=”MyListSelector”>
..stuff
</LongListSelector>
<TextBlock x:Name=”MyError” Visibility=”Collapsed”> </TextBlock>
</StackPanel>
Catch (Exception Ex)
{
MyListSelector.Visibility = Visibility.Collapsed
MyError.Visibility = Visibility.Visible
MyError.Text = Ex.Message;
}
you can hide the Longlist selector and add the Textbox with the Error message directly from the code behind. see the code below.
try
{
//make the service call and do your stuff
}
catch(exception ex)
{
MyListSelector.Visibility = Visibility.Collapsed;
var errorTextBox = new TextBox();
errorTextBox.Text = "some Error has occured";
//add all the properties you want to add for textbox such as color,height,fontsiz ect..
//Name your pivotitem control, say pivotitem1
pivotitem1.Content = errorTextBox;
}
hope this helps.
Note: uncompiled code. pardon compilation errors