WP7 Updating Pivot control title - data-binding

I have a Pivot control which I am using as following within the XAML.
I have bound the Pivot Title to a method on my view model as its content will vary depending upon what is being displayed.
<controls:Pivot x:Name="MainPivot" ItemsSource="{Binding PivotItemHeaders}" Title="{Binding ApplicationTitle}" >
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Description}"/>
</DataTemplate>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemTemplate>
<DataTemplate>
<ListBox x:Name="EventsListbox"
ItemsSource="{Binding allEventItems}"
ItemTemplate="{StaticResource EventDisplay3}"
SelectionChanged="EventsListbox_SelectionChanged"/>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
The collection of items is being refreshed and the binding is working fine for these objects - however the Pivot title is not refreshing with the new value.
It seems stuck at the value when the page/pivot control was first shown.
Any ideas how I can get the pivot control to refresh? - Thanks

I just did a quick test, binding works just fine:
<controls:Pivot Title="MY APPLICATION" ItemsSource="{Binding Items}">
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding LineOne}" />
</DataTemplate>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemTemplate>
<DataTemplate>
<Grid>
<Button Content="Update" Click="Button_Click" />
</Grid>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
And in the C#
private void Button_Click(object sender, RoutedEventArgs e)
{
App.ViewModel.Items.Clear();
App.ViewModel.Items.Add(new ItemViewModel() { LineOne = "foo" });
App.ViewModel.Items.Add(new ItemViewModel() { LineOne = "bar" });
App.ViewModel.Items.Add(new ItemViewModel() { LineOne = "baz" });
}
So clearly you're doing something very wrong. Post your code and we'll take a look.
Update
Title Binding also works
XAML
<controls:Pivot Title="{Binding Title}">
<controls:PivotItem Header="first">
<Grid>
<Button Click="Button_Click" Content="OK!" />
</Grid>
</controls:PivotItem>
</controls:Pivot>
C#:
private void Button_Click(object sender, RoutedEventArgs e)
{
Title = "foobar!";
PropertyChanged(this, new PropertyChangedEventArgs("Title"));
}

Related

When change an object inside a CollectionView multiple objects are affected

If I hide an image visibility in CollectionView, multiple image visibility is affecting but image Tapped event fires once.
Simplified CollectionView xaml..
<CollectionView x:Name="favCollectionView"
ItemsSource="{Binding FavoriteCollection}"
RemainingItemsThresholdReachedCommand="{Binding GetNextDatas}"
RemainingItemsThreshold="1"
ItemSizingStrategy="MeasureAllItems"
ItemsLayout="VerticalList"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid VerticalOptions="FillAndExpand">
<Label Grid.Row="0" Text="{Binding TargetText}"/>
<Image Grid.Row="0" Aspect="AspectFill" Source="seeResult.png">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Tapped_TranslatedResult"/>
</Image.GestureRecognizers>
</Image>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Code behind..
void Tapped_TranslatedResult(System.Object sender, System.EventArgs e)
{
var img = sender as Image;
if (img != null)
{
img.Opacity = 0;
}
}
For example, If I have 50 rows in CollectionView and tapped once top second image item, next ninth image's visibility is changed too and again next ninth one too, so on..
What could be the problem?
I changed the Image to ImageButton and then added Command parameter. The key was the Jason's comment. Binding the Model property to my ImageButton's IsVisibility property and it worked correctly.

Xamarin - How to call a function in Collection View without error?

I'm trying to call a function in a Xamarin project by using the SelectionChanged property.
Inside this property, I've called a function that I've declared in the cs file.
Here is the XAML code:
<CollectionView x:Name="PCCollection" SelectionMode="Single" SelectionChanged="Cell_Tapped" AutomationId="{Binding Tipologia_Alimento}">
Here is the CS function:
private async void Cell_Tapped(object sender, System.EventArgs e) {
Console.WriteLine("Tapped");
Console.WriteLine((sender as Cell).AutomationId.ToString());
}
When I click on the Collection View cell, it prints the value "Tapped" but it gives me also the Break Mode error: "The application is in break mode".
Could you help me with this error?
Thanks in advance.
Your syntax is not valid. The Collection View control does not have AutomationId property.
Sample
<CollectionView ItemsSource="{Binding Monkeys}"
SelectionChanged="Cell_Tapped"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
void Cell_Tapped(object sender, SelectionChangedEventArgs e)
{
if (((CollectionView)sender).SelectedItem == null)
return;
string current = (e.CurrentSelection.FirstOrDefault() as Monkey)?.Name;
}
You can find more here
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/selection
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/collectionview/populate-data

Xamarin CollectionView - Scroll Programatically

I have collection view . See below code
<CollectionView ItemsSource="{Binding photos}" HeightRequest="300"
ItemSizingStrategy="MeasureAllItems" Margin="10,0,10,0"
x:Name="photosView"
ItemsUpdatingScrollMode="KeepScrollOffset">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="3" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="2">
<Frame BackgroundColor="Red" HeightRequest="79" WidthRequest="53" Padding="0" Margin="0"
IsClippedToBounds="True" HasShadow="False" CornerRadius="10">
<Image Aspect="AspectFill" Source="{Binding imageUrl}"/>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
I am showing 3 rows and 3 columns of the images. If I have more than 9 images then I am showing Button which says Scroll for more photos. Now On click on the imageI have below code
void OnScrollMore(System.Object sender, System.EventArgs e)
{
//photosView.SendScrolled(new ItemsViewScrolledEventArgs() { FirstVisibleItemIndex = 0 });
photosView.ScrollTo(photosView.Y + 10, position: ScrollToPosition.MakeVisible, animate: true);
}
But nothing is happening . It is not getting scrolled to next row.
Any suggestions?
The reason your ScrollTo method is not working is because the photosView can't find the item 'photosView.Y + 10' in your photosView itemssource. The method you're invoking is trying to find an item in the ItemsSource. It is not scrolling to a y-position like you're trying to do. You can see it in the description of the method when going to the definition. It is waiting for an 'object item'.
public void ScrollTo(object item, object group = null, ScrollToPosition position = ScrollToPosition.MakeVisible, bool animate = true);
If what you're trying to do is scroll to the last added item of the collectionview, then try this working approach and build it up from there. Here everytime you press the button, an item (string) gets added. This item is set as the ScrollTo object at the end of the button click handler.
MainPage.xaml
<StackLayout Orientation="Vertical">
<CollectionView ItemsSource="{Binding photos}" HeightRequest="300"
ItemSizingStrategy="MeasureAllItems" Margin="10,0,10,0"
x:Name="photosView"
ItemsUpdatingScrollMode="KeepLastItemInView">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="3" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="2">
<Frame BackgroundColor="Red" HeightRequest="79" WidthRequest="53" Padding="0" Margin="0"
IsClippedToBounds="True" HasShadow="False" CornerRadius="10">
<Label Text="{Binding}" TextColor="White"
HorizontalOptions="Center" VerticalOptions="Center"
HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button Text="scroll more" HorizontalOptions="Center" VerticalOptions="End" Clicked="OnScrollMore"/>
</StackLayout>
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
ObservableCollection<string> ObservableItems { get; set; }
public MainPage()
{
InitializeComponent();
ObservableItems = new ObservableCollection<string>(new List<string>() { "een", "twee", "drie" });
photosView.ItemsSource = ObservableItems;
}
void OnScrollMore(System.Object sender, System.EventArgs e)
{
var item = (ObservableItems.Count + 1).ToString();
ObservableItems.Add(item);
photosView.ScrollTo(item, position: ScrollToPosition.MakeVisible, animate: true);
}
}
Resulting in:

BindingMode=TwoWay in codebehind

Edit: apologies for the bad title, apparently something like "Setting bindingmode in code behind" didn't fit the highly nebulous requirements of SO. A title that is clearly more obvious than what the current one is.
Original: I am trying to set the binding of my listview in the code behind of its data selector template. The reason i am doing this, as I suspect (because doing something similar to it in a different template selector fixed it) that once you exit that page android seems to still contain a reference to it and then throws a amarin.forms.platform.android.viewcellrendererA disposed object exception.
my current xaml looks as follows:
<StackLayout Orientation="Vertical"
Padding="0, 20, 0, 0"
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand">
<Label
x:Name="LabelName"
FontAttributes="Bold"
TextColor="Black"
FontSize="14"
VerticalOptions="Start"
HorizontalOptions="FillAndExpand"/>
<ListView x:Name="MultiselectList"
SeparatorVisibility="None"
RowHeight="30"
Margin="0, 10, 0, 0"
VerticalOptions="FillAndExpand"
HorizontalOptions="StartAndExpand"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<customcontrols:NoHighlightCell>
<StackLayout Orientation="Horizontal"
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand">
<Image
x:Name="image"
Source="{Binding ImageUrl}"
VerticalOptions="StartAndExpand"
HorizontalOptions="Start"
Margin="0, 2, 0, 0"
WidthRequest="15"
HeightRequest="15" />
<Label
x:Name="name"
Text="{Binding Name}"
TextColor="Black"
VerticalOptions="StartAndExpand"
FontSize="14"
HorizontalOptions="Start"/>
</StackLayout>
</customcontrols:NoHighlightCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Label Text="Selection required"
TextColor="Red"
Margin="0, 10, 0, 0"
IsVisible="{Binding ValidationRequired}"
VerticalOptions="StartAndExpand"
HorizontalOptions="FillAndExpand"
FontSize="14"/>
</StackLayout>
Here's my code behind:
private SoapNoteControlsViewModel viewModel;
public SelectListTemplate()
{
InitializeComponent();
}
protected override void OnDisappearing()
{
base.OnDisappearing();
}
protected override void OnAppearing()
{
base.OnAppearing();
LabelName.Text = viewModel.Label;
MultiselectList.ItemsSource = viewModel.CheckboxItems;
MultiselectList.SelectedItem = viewModel.SelectedItem;
//how would i set the BindingMode here? Doing .SetBinding doesn't seem to do it.
}
protected override void OnBindingContextChanged()
{
try
{
base.OnBindingContextChanged();
if(BindingContext == null)
{
return;
}
viewModel = BindingContext as SoapNoteControlsViewModel;
} catch (Exception e)
{
Console.WriteLine(e);
}
}
}
I tried doing .SetBinding, but it keeps saying that BindingMode is a type (given that it is an enum). Looking at some of the examples on MSDN haven't really helped
You would do it like this:
MultiselectList.SetBinding(ListView.ItemsSourceProperty, nameof(viewModels.CheckboxItems), BindingMode.TwoWay);
The first parameter is the property that you want to bind to - e.g. the ItemsSource.
The second parameter is the name of the property to look for - e.g. your viewModel's CheckBoxItems. This collection will be bound/populated in the list.
The last parameter is what you would want to achieve - the BindingMode. You are correct in saying that it is an enum, so here we can set it to BindingMode.TwoWay.
For reference: BindingMode's Remarks page.

Collection view master menu xamarin forms

I'm study Xamarin, I have Xamarin Forms using Collection View. I want to create master menu on home page in android. I can't auto change show view item in Collection View.
enter image description here
Bind the ItemTemplate to a DynamicResource and change the Resource on a button click or where you want the change to happen.
Define the templates in resource of the page.
<ContentPage.Resources>
<DataTemplate x:Key="menuTemplate1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition Width="0.7*" />
</Grid.ColumnDefinitions>
<Image Source="https://i.stack.imgur.com/di65V.jpg?s=328&g=1" />
<StackLayout Grid.Column="2">
<Label Text="Hi there" />
<Label Text="Hi there" />
</StackLayout>
</Grid>
</DataTemplate>
<DataTemplate x:Key="menuTemplate2">
<Image Source="https://i.stack.imgur.com/di65V.jpg?s=328&g=1" />
</DataTemplate>
</ContentPage.Resources>
Initialize DynamicResource in Page.Xaml.cs
public MainPage()
{
InitializeComponent();
Resources["menuTemplate"] = Resources["menuTemplate1"];
}
Bind the DynamicResource toItemTemplate`
<CollectionView ItemTemplate="{DynamicResource menuTemplate}" ItemsSource="{Binding ItemCollection}" />
Change the DynamicResource on button click or where you want.
void Button_Clicked(System.Object sender, System.EventArgs e)
{
if(Resources["menuTemplate"] == Resources["menuTemplate1"])
{
Resources["menuTemplate"] = Resources["menuTemplate2"];
}
else
{
Resources["menuTemplate"] = Resources["menuTemplate1"];
}
}
Please do check and comment for any query.

Resources