Modify last (or individual) item inside GridView - c#

I have a GridView which is populated (through binding) by an ObservableCollection. How do I set it up so that every time a new item is added to the ObservableCollection, the last item in the GridView always has a button on top of it ?
This is the XAML of the GridView's ItemTemplate
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="White">
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding DateMade}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
My problem lies in this template being applied for all items in the GridView. I want it so that if it's the last item (and the last item would keep changing every time a new item is added), the above StackPanel should be replaced by another control (say, a button). How would I go about doing this ?

I would extend the template of all elements but hide the additional element and only show it if it's the latest element (specified by some bool property that is set to true on the last element). Something like this.
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="White">
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<Button Visibility="{Binding IsLastElement, Converter={StaticResource BoolToVisibilityConverter}}"/>
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding DateMade}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
I think another option is to change the DataTemplate dynamically using TemplateSelecting event, on changing content of elements, but it would be a little bit more work.
There might be better solutions though.
Edit
Decided to share some links for the aforementioned idea (Which I've used in WinRT) and another one available in WPF
WPF Based Dynamic DataTemplateSelector - used similar approach in WinRT
DataTemplateSelector - tried slightly modified example and works fine

Related

Binding Text on TextBlock not show the whole text windows phone 8

I've got an issue that the TextBlock not showing fully while the string is more than 1000 characters.
I've tried use this code
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
or
VerticalAlignment="Stretch" on my TextBlock
or use this code
<ListBox ItemsSource="{Binding ArticleDataDetail}" ScrollViewer.VerticalScrollBarVisibility="Visible">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding TaxoName}" Style="{StaticResource PhoneTextNormalStyle}" Foreground="#FF2976B9"/>
<TextBlock Text="{Binding Title}" FontWeight="Bold" TextWrapping="Wrap" Style="{StaticResource PhoneTextTitle3Style}"/>
<Image Source="{Binding Picture}" Width="auto" Name="articleImage" Margin="10"/>
<TextBlock Text="{Binding Content}" TextWrapping="Wrap"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But It still not show.
my code:
<Grid Margin="12,0,12,0" DataContext="{Binding ArticleDataDetail[0]}">
<ScrollViewer HorizontalScrollBarVisibility="Disabled">
<StackPanel>
<TextBlock Text="{Binding Content}" TextWrapping="Wrap" VerticalAlignment="Stretch"></TextBlock>
<TextBlock Text="GeuT"></TextBlock>
</StackPanel>
</ScrollViewer>
</Grid>
Do you mean the TextBlock in the ItemTemplate? If it's the case maybe this helps:
Set the HorizontalContentAlignment attribute of the ListBox to "Stretch":
<ListBox ... HorizontalContentAlignment="Stretch"></ListBox>
I'm just guessing what your problem is, so if it's not the case I think you should make your question clearer: rephrase it or add some illustrating images.
Another thing I could think of - without a screenshot - is that maybe the Textblock is too small to fit all the content and that it would have to be scrollable.
Scrollbars don't appear automatically if the text exceeds the display item size limits. You can enable them by adding the following properties to your TextBlocks:
ScrollViewer.VerticalScrollMode="Auto" ScrollViewer.VerticalScrollBarVisibility="Visible"

Display list of countries in Windows Phone 8.1

I am writing a Windows Phone 8.1 App (WINRT)
I want to display a list of countries in registration page out of which user can select one. In Windows Phone 7, we used to have LongListSelector.
What is its replacement in Windows Phone 8.1 (WinRT).
Actually, I want users to click on this control and it should open in fullscreenmode.
I am confused between ListView, ListBox, Semanticzoom
I am currently using:
<ListView
Name="UserCountry_ListPicker"
FullModeHeader="Select Country:"
SelectedIndex="-1"
Foreground="{StaticResource DefaultTheme_DarkBlueColor}"
FontWeight="ExtraLight"
Margin="0,5,0,0"
BorderBrush="{StaticResource DefaultTheme_DarkBlueColor}"
BorderThickness="0.2,0.2,0.2,3"
VerticalContentAlignment="Bottom"
VerticalAlignment="Bottom"
Background="{StaticResource DefaultTheme_TextBoxBackground_Light}"
SelectionChanged="UserCountry_ListPicker_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Horizontal"
Margin="0,0,0,0">
<Border
Background="{StaticResource DefaultTheme_DarkBlueColor}"
Width="28"
Height="28">
<TextBlock
Text="{Binding CountryWithCodesGroupItem_Symbol}"
FontSize="14"
FontWeight="ExtraLight"
Foreground="WhiteSmoke"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<TextBlock
Text="{Binding CountryWithCodesGroupItem_Name}"
FontWeight="ExtraLight"
Margin="12 0 0 0"
FontSize="21"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.FullModeItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Horizontal"
Margin="20,5,0,5"
>
<Border
Background="{StaticResource DefaultTheme_DarkBlueColor}"
Width="68"
Height="68">
<TextBlock
Text="{Binding CountryWithCodesGroupItem_Symbol}"
FontSize="26"
FontWeight="ExtraLight"
Foreground="WhiteSmoke"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<TextBlock
Text="{Binding CountryWithCodesGroupItem_Name}"
FontWeight="ExtraLight"
Name="CountryNames"
Margin="12 0 0 0"
Foreground="{StaticResource DefaultTheme_DarkBlueColor}"
FontSize="26"
VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListView.FullModeItemTemplate>
<ListView.HeaderTemplate>
<DataTemplate>
<StackPanel
Orientation="Horizontal"
Margin="0,0,0,-5">
<TextBlock
Name="UserCountry_Label"
FontSize="25"
FontWeight="ExtraLight"
Foreground="{StaticResource DefaultTheme_DarkBlueColor}"
Text="Country">
</TextBlock>
<Image Source="ms-appx:///Images/Login_RegistrationPage/athteriskRedForm_01.png"
Margin="3,0,0,0">
</Image>
</StackPanel>
</DataTemplate>
</ListView.HeaderTemplate>
</ListView>
But it shows opened list on page. Can't I have it closed on page like this:
example image
Maybe you will consider using ListPickerFlyout:
<Button Content="Choose country">
<Button.Flyout>
<ListPickerFlyout ItemsSource="{Binding CountryList}" Placement="Full" ItemsPicked="Items_PickedEven">
<ListPickerFlyout.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding CountryName}"/>
</DataTemplate>
</ListPickerFlyout.ItemTemplate>
</ListPickerFlyout>
</Button.Flyout>
</Button>
You may also think of using general Flyout and define it's content as ListView, ListBox or other.
As far as the differences between the three are concerned, ListView is essentially like a ListBox however it also has a View property that ListBox does not have. The View property is useful for specifying a prefdefined way to display items.
A SemanticZoom control often has a ListView control within it, and allows you to switch between two different views of the list's data set.

Windows 8 metro app: Accessing the button property

I am new to windows 8.1 development.
I created the pages below with the button on the xaml page
GroupedItemsPage.xaml.cs
GroupedItemsPage.xaml
<Button Style="{StaticResource mystyle}" Click="ItemView_ItemClick" x:Name="Testing">
I was thinking that on page load of the xaml page I will be able to have access to the button property
by doing something like this .. Testing.property as we normally do in the windows development environment. This is not happening. I want to be able to style some buttons programmatically.
How can I get the property of the button in the .cs file?
Thanks. Here is the xaml page below.
<GridView
x:Name="itemGridView"
AutomationProperties.AutomationId="ItemGridView"
AutomationProperties.Name="Grouped Items"
Grid.RowSpan="2"
Padding="116,137,40,46"
ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
SelectionMode="None"
IsSwipeEnabled="false"
>
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="Auto" Height="Auto" >
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding Subtitle}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>-->
<Button Style="{StaticResource contactSquarePref}" Click="ItemView_ItemClick" x:Name="Testing">
<StackPanel Margin="5" >
<TextBlock Tag="cntCustName" Style="{ThemeResource CntNormalTextBlockStyle}" Text="{Binding Name }"/>
<TextBlock Tag="cntCatCode" Style="{ThemeResource CntLrgTextBlockStyle}" Text="{Binding Address}"/>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid GroupPadding="0,0,70,0"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid Margin="0,0,0,2">
<Button Foreground="{ThemeResource ApplicationHeaderForegroundThemeBrush}"
AutomationProperties.Name="Group Title"
Click="Header_Click"
Style="{StaticResource TextBlockButtonStyle}" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ContactType}" Margin="0,-11,10,10" Style="{StaticResource SubheaderTextBlockStyle}" TextWrapping="NoWrap" />
<TextBlock Text="{StaticResource ChevronGlyph}" FontFamily="Segoe UI Symbol" Margin="0,-11,0,10" Style="{StaticResource SubheaderTextBlockStyle}" TextWrapping="NoWrap" />
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
It depends on your XAML. If your button is just a child element (i.e. part of your logical tree) or a named resource of your page, there'll be no problem, there's a code generation process on build, that creates required fields (in this case Button Testing) and finds required elements in InitializeComponent() generated method.
But if your button is a part of control template the only way to get reference to your element is GetTemplateChild() (if you're writing your own control, as this method is protected) or manually observing Visual Tree.
So, if you have a problem with the child element of your page, past all of your XAML markup here, as the line in the question above is not enough to find solution. But if you've defined button in control template, look at the second paragraph.

A good example on how to use UpdateSourceTrigger=Explicit with MVVM

I'm trying to figure out how to use UpdateSourceTrigger=Explicit.
I've got following form:
<StackPanel x:Name="LayoutRoot" Margin="10" DataContext="{Binding ElementName=Window, Mode=OneWay}">
<DockPanel>
<TextBlock Text="Proxy address:" VerticalAlignment="Center"/>
<TextBox Text="{Binding User.PageAddress, Mode=TwoWay, UpdateSourceTrigger=Explicit}" Margin="28,0,0,0"/>
</DockPanel>
<DockPanel Margin="0,5,0,0">
<TextBlock Text="User name:" VerticalAlignment="Center"/>
<TextBox Text="{Binding User.UserName, Mode=TwoWay, UpdateSourceTrigger=Explicit}" Margin="46,0,0,0"/>
</DockPanel>
<DockPanel Margin="0,5,0,0">
<TextBlock Text="User password:" VerticalAlignment="Center"/>
<TextBox Text="{Binding User.Password, Mode=TwoWay, UpdateSourceTrigger=Explicit}" Margin="26,0,0,0"/>
</DockPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,5,0,0">
<Button Content="Ok" IsDefault="True" Width="70" Margin="0,0,15,0" Click="Ok_Click"/>
<Button Content="Cancel" IsCancel="True" Width="70"/>
</StackPanel>
</StackPanel>
what method should I call to update User property?
I don't want to address the elements by x:Name to invoke the binding. If I have to address the elements by x:Name, I as well can go without binding altogether, as far as I'm concerned.
You need to call BindingExpression.UpdateSource in the code behind to manually update the binding. Explicit binding isn't really compatible with MVVM since you need to directly reference the view objects to perform the manually update.
// itemNameTextBox is an instance of a TextBox
BindingExpression be = itemNameTextBox.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();

how to acess on controls inside of stackpanel in windows phone7?

i design page bellow code.
<ScrollViewer VerticalScrollBarVisibility="Visible" Grid.Row="1" x:Name="svProduct">
<StackPanel>
<ItemsControl x:Name="lstSearchResult" ItemsSource="{Binding Path=PIProductList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Width="480" Style="{Binding CellStyle}" Orientation="Horizontal" VerticalAlignment="Center" Height="50" >
<TextBlock Foreground="Black" FontSize="20" Width="320" FontFamily="Tahoma" Margin="10,0,0,0" Text="{Binding Title}" VerticalAlignment="Center" TextWrapping="Wrap"></TextBlock>
<Button Name="btnBookmark" Click="btnBookmark_Click" Tag="{Binding}" Background="Transparent">
<Button.Content>
<Image Source="/Images/bookmarks_red.png" Width="33" Height="30" VerticalAlignment="Top" Margin="-15"></Image>
</Button.Content>
</Button>
<Button BorderThickness="0" x:Name="btnSubmit" Click="btnSubmit_Click" Background="Transparent" Tag="{Binding}" >
<Button.Content>
<Image Name="ram" Source="/Images/blue_arrow.png" Width="40" Height="40" VerticalAlignment="Top" Margin="-15"></Image>
</Button.Content>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
i want to access for btnBookmark visuble false .
can't access btnBookmark.Visibility=Visibility.collapsed
how to do this?
please help to me...........
The best way I know to do this is to create a Visiblity property on your item ViewModel (the one that is bound to each row in your ItemsControl) and toggle that value based on the changes to each item, presumably via the toggle button in each row. I don't know of a good way to "loop and look" for these internal controls. You're much better off using the existing data binding infrastructure to manage this for you.

Categories

Resources