I have the following problem in Carousel Fri, where in Android and iOS it works, in Windows Universal Mobile gives the following error:
EmptyClass k = new EmptyClass();
lista = new List<Dados>();
lista.Add(new Dados
{
titulo = k.Title1.Substring(1)
});
lista.Add(new Dados
{
titulo = k.Title2.Substring(1)
});
lista.Add(new Dados
{
titulo = k.Title3.Substring(1)
});
MAinCarousel.ItemsSource = lista;
This is my .xaml layout:
<cv:CarouselView x:Name="MAinCarousel" >
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label TextColor="White" Text="{Binding titulo}" FontSize="18" HorizontalOptions="Start" Font="Bold" VerticalOptions="CenterAndExpand"/>
</Grid>
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView>
Xamarin's CarouselView has been neglected for quite a while now. I'm pretty sure they have plans to make it stable at some point but for now it's not very usable (at least for me it hasn't been). It's very possible that the updates to UWP have rendered it useless.
I'd advice you to look into a 3rd party CarouselView implementation that not only works but has a wider feature set than what Xamarin provides. Take a look at it here: https://github.com/alexrainman/CarouselView
Android, iOS and UWP are all supported and the updates keep on coming regularly. On top of all that, the usage is very similar to Xamarin's version.
Disclaimer: I have no affiliation with the project. Just a happy user with three projects utilizing the library.
Related
Is there any way we can create Carousel View instead of Carousel page so that only portion of the page swipes left or right. Also I want to create this control in the Xamarin Forms and not specific to platform.
If we need to create this custom control in the xamarin.android or xamarin.iOS then what is the real benefits of using the Xamarin.forms where this simple requirements are not getting satisfied.
There's a well documented CarouselView project hosted on github:
https://github.com/chrisriesgo/xamarin-forms-carouselview
and
http://chrisriesgo.com/xamarin-forms-carousel-view-recipe/
The nuget package for the CarouselView is now available (v2.3.0-pre1):
https://www.nuget.org/packages/Xamarin.Forms.CarouselView/2.3.0-pre1
We can use the CarouselView which was introduced in Xamarin forms 4.3. Now in Xamarin 4.6, we don't have to use the Forms.SetFlags("CollectionView_Experimental"); in appdelegate of iOS and mainactivity of android.
However, to use the indicatorview for the Carousel page we have to set this
Forms.SetFlags("IndicatorView_Experimental"); in appdelegate of iOS and mainactivity of android.
I have just implemented a similar thing. To create the a carousel view, I just created a horizontal Stacklayout, wrapped in a horizontal scroll view.
In my particular example, I needed to create an image gallery. I used the Camera control from the Xamarin.Labs project to get the image from either the camera roll or the camera itself. I then added this as a child to the Stacklayout.
Hope this helps.
As of Xamarin.Forms V2.2.0-pre1 CarouselView has now been added to Xamarin.Forms.
CarouselView
CarouselView is intended to fully replace CarouselPage. CarouselPage
will be deprecated in a future release. CarouselView is superior in
many ways, including its ability to be virtualized and nested within
layouts.
See https://forums.xamarin.com/discussion/63983/xamarin-forms-2-2-0-pre1-released#latest
Unfortunately there is no documentation on this as of yet.
EDIT:
CarouselView was Removed for Xamarin.Forms V2.2.0.31 because it wasn't ready for stable release. But from the look of it it will be merged back soon.
For now you can find the seperate CarouselView nuget package here: https://www.nuget.org/packages/Xamarin.Forms.CarouselView/2.3.0-pre1
and you can use it like so:
Namespace:
xmlns:cv="clr-namespace:Xamarin.Forms;assembly=Xamarin.Forms.CarouselView"
Then we can simply add the CarouselView at the top of our page:
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height=".3*"/>
<RowDefinition Height=".7*"/>
</Grid.RowDefinitions>
<cv:CarouselView ItemsSource="{Binding Zoos}" x:Name="CarouselZoos">
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.RowSpan="2" Aspect="AspectFill" Source="{Binding ImageUrl}"/>
<StackLayout Grid.Row="1" BackgroundColor="#80000000" Padding="12">
<Label TextColor="White" Text="{Binding Name}" FontSize="16" HorizontalOptions="Center" VerticalOptions="CenterAndExpand"/>
</StackLayout>
</Grid>
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView>
<!--List of Monkeys below-->
</Grid>
more info: https://blog.xamarin.com/flip-through-items-with-xamarin-forms-carouselview/
If you use Xamarin.Forms V2.2.0-pre1 and you need to display different views for each page, you can use a derived class like that:
public class CarouselViewMultiPage : CarouselView
{
List<View> _children = new List<View> { };
public List<View> Children {
get { return _children; }
set {
_children = value;
OnPropertyChanged();
}
}
public CarouselViewMultiPage ()
{
this.ItemTemplate = new CarouselTemplateSelector();
this.ItemsSource = Children;
this.SetBinding(CarouselView.ItemsSourceProperty, "Children");
BindingContext = this;
}
}
public class CarouselTemplateSelector : DataTemplateSelector
{
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
DataTemplate dt = new DataTemplate();
View civ = (View)item;
return new DataTemplate(() =>
{
return civ;
});
}
}
so you can call it passing Views:
public App()
{
// The root page of your application
MainPage = new ContentPage {
Content = new CarouselViewMultiPage
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Children =
{
new Label() { Text="Page 1"},
new Label() { Text="Page 2"},
new Label() { Text="Page 3"},
}
}
};
}
CarouselView has been introduced in Xamarin forms v4.4. You can have a look at this. In additional to CarouselView, IndicatorView is also added to indicate the nth item in the carousel.
I am new to Xamarin. I am trying to create a sample in Xamarin forms with 5 custom horizontallistviews (I have used renderers to achieve the same in different platforms. It works perfectly (scrolls horizontally) when I have only 2 of these controls on screen. When I add all the 5 I have to add these controls inside a ScrollView oriented vertically so that I can see all the controls. When I do that I am only able to scroll the page vertically. I am not able to scroll the individual controls (horizontallistviews) horizontally.
This issue is only with Android. It works fine in Windows Phone.
Below is my code:
<ScrollView Orientation="Vertical">
<StackLayout Padding="5, 25" Orientation="Vertical" VerticalOptions="FillAndExpand">
<Image Source ="label_entertainment.png" HorizontalOptions="Start"/>
<local:HorizontalListViewEntertainment x:Name="entertainmentView" Items="{Binding Entertainment}" HeightRequest="198"/>
<Image Source ="label_music.png" HorizontalOptions="Start"/>
<local:HorizontalListViewMusic x:Name="musicListView" Items="{Binding Music}" HeightRequest="198"/>
<Image Source ="label_movies.png" HorizontalOptions="Start"/>
<local:HorizontalListViewMovies x:Name="movieListView" Items="{Binding Movies}" HeightRequest="198"/>
<Image Source ="label_celebrities.png" HorizontalOptions="Start"/>
<local:HorizontalListViewCelebrities x:Name="celebritiesListView" Items="{Binding Celebrities}" HeightRequest="198"/>
<Image Source ="label_style.png" HorizontalOptions="Start"/>
<local:HorizontalListViewStyle x:Name="styleListView" Items="{Binding Celebrities}" HeightRequest="198"/>
</StackLayout>
</ScrollView>
I found a solution here. However it doesn't work in my case because I don't have inner scroll views. Please help. Thank you!
I found the solution. I just had to add the following code to the CustomRenderer of the horizontallistviews in android.
public override bool DispatchTouchEvent(MotionEvent e)
{
switch (e.Action)
{
case MotionEventActions.Down:
StartX = e.RawX;
StartY = e.RawY;
this.Parent.RequestDisallowInterceptTouchEvent(true);
break;
case MotionEventActions.Move:
if (IsHorizontal * Math.Abs(StartX - e.RawX) < IsHorizontal * Math.Abs(StartY - e.RawY))
this.Parent.RequestDisallowInterceptTouchEvent(false);
break;
case MotionEventActions.Up:
this.Parent.RequestDisallowInterceptTouchEvent(false);
break;
}
return base.DispatchTouchEvent(e);
}
Referred this
have you tried using both ScrollViewand HorizontalScrollView ? http://android-code-crumbs.blogspot.ro/2011/06/how-to-set-horizontal-and-vertical.html
What can I do in the following situation?
I have a simple page. In code behind I add PhoneTextBox control for some filtering of a data. But sometimes (frequently) when I try to write something, I see, that text inside is transparent or collapsed or something else, so I don't see it. I don't see it even when I select this text.
// Generating of a PhoneTextBox
SearchBox = new Microsoft.Phone.Controls.PhoneTextBox();
SearchBox.DataContext = searchBoxContext;
SearchBox.Name = string.Format("SearchBox_{0}", Guid.NewGuid());
SearchBox.Visibility = Visibility.Collapsed;
// Adding Phone text box in a Grid on the Page
RowDefinition rd = new RowDefinition();
rd.Height = GridLength.Auto;
PageDynamicGrid.RowDefinitions.Insert(0, rd);
Grid.SetRow(generator.SearchBox, 0);
foreach (FrameworkElement child in PageDynamicGrid.Children)
{
Grid.SetRow(child, Grid.GetRow(child) + 1);
}
SearchBoxContext = (generator.SearchBox.DataContext as SearchButtonModel);
SearchBoxContext.SearchTextChanged += SearchBoxContext_SearchTextChanged;
generator.SearchBox.TextChanged += SearchBox_TextChanged;
generator.SearchBox.LostFocus += SearchBox_LostFocus;
generator.SearchBox.KeyUp += SearchBox_KeyUp;
generator.SearchBox.DataContext = null;
PageDynamicGrid.Children.Add(generator.SearchBox);
PageDynamicGrid.UpdateLayout();
and page.xaml
<Grid x:Name="PageDynamicGrid" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="{Binding Title}"
Style="{StaticResource PhoneTextTitle1Style}" />
</StackPanel>
<ListBox Grid.Row="1" Margin="12,0"
ItemsSource="{Binding PageDynamicContent, Mode=OneWay}"/>
</Grid>
Almost all content of this page (including search box) creates dynamically, but other content is some buttons and links and I need to filter it, if I have search box. Filter works, but users don't like collapsed text in search box. So it looks like that (and there is not a whitespaces in front of the marker)
So, i don't know why, but it seemed that problem is in the order of actions:
First of all create element, change grid column and row definitions
and add element in the grid.
Update layout of the grid.
And only after all this actions we can collapse PhoneTextBox.
it works for me.
I would like my ads to be shown while my app is trialed and disappear when app is fully licensed.
Kookiz-
Private Sub PhoneApplicationPage_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs)
If App.IsTrial Then
AdControl1.Visibility = Windows.Visibility.Visible
Else
AdControl1.Visibility = Windows.Visibility.Collapsed
End If
End Sub
The problem is that IsEnabled still shows the Control.
What you should do is add an empty container for the ad in your XAML file, like this:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="spAd" Grid.Row="0">
<!--Ad will be placed here via the code-->
</StackPanel>
</Grid>
Then in the PhoneApplicationPage_Loaded event handler, if IsTrial equals true, instanciate the AdControl and add it to the View:
AdControl _adControl = new AdControl();
// Use your real Application ID and Ad Unit ID here
_adControl.ApplicationId = "test_client";
_adControl.AdUnitId = "Image480_80";
_adControl.Width = 480;
_adControl.Height = 80;
spAd.Children.Add(_adControl);
I'm trying to get an element to fire the MouseUp event when the user clicks/taps outside of it, drags into it, then lets go. This type of functionality works in Silverlight, but not WP7. I can't figure out how to get it to work in WP7.
I created a simple app that demonstrates this. In a brand new WP7 app I added this to the content panel:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1" MouseLeftButtonUp="Grid_MouseLeftButtonUp" Background="Green" />
<Grid x:Name="g2" Grid.Row="1" MouseLeftButtonUp="Grid_MouseLeftButtonUp" Background="Blue" />
</Grid>
Then the Grid_MouseLeftButtonUp handler in the codebehind:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
System.Diagnostics.Debug.WriteLine("MouseUp in " + (sender as Grid).Name);
(sender as Grid).Background = new SolidColorBrush(Colors.Red);
}
Run this app and notice the MouseUp event fires fine if you release the button in the same cell you pressed down, however it doesn't fire if you drag from one cell to the other. How can I make the MouseUp event fire?
P.S. I also posted this on the app-hub forms, but no response yet: http://forums.create.msdn.com/forums/p/98004/584400.aspx
My solution is a bit like ShawnFeatherly's, but without TouchFrame.
Basically, as he says, if you call MouseCapture from the grid where the MouseDown event occured, the MouseUp will be triggered on the same grid. So we know how to be notified when MouseUp occurs, the only problem left is how to know in which grid the MouseUp actually occured.
For this, we're going to use the VisualTreeHelper.FindElementsInHostCoordinates method, as it returns all the elements at a specified coordinate.
So, first add a MouseLeftButtonDown event handler to each of your grids:
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
((Grid)sender).CaptureMouse();
}
Now in the MouseLeftButtonUp event handler of each of your grids, first release the mouse capture, then retrieve the Grid in which the MouseUp occured:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var grid = (Grid)sender;
grid.ReleaseMouseCapture();
var mouseUpGrid = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel)
.OfType<Grid>()
.FirstOrDefault();
if (mouseUpGrid != null)
{
Debug.WriteLine("MouseUp in " + mouseUpGrid.Name);
mouseUpGrid.Background = new SolidColorBrush(Colors.Red);
}
}
Note that a problem may occurs depending on your visual tree: if you have multiple grids and wants to detect the MouseUp only on some, you need a way to identify them. For this, I suggest to use the Tag property. Tag is an all-purpose field available on each control, that you can use however you need. It's especially useful for identification purposes.
Start by adding it to the grids that interest you:
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0"
MouseLeftButtonUp="ContentPanel_MouseLeftButtonUp">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1"
Background="Green"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
<Grid x:Name="g2"
Grid.Row="1"
Background="Blue"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
</Grid>
Then use exactly the same logic in code-behind, but this time add a filter when browsing the visual tree:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var grid = (Grid)sender;
grid.ReleaseMouseCapture();
var mouseUpGrid = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel)
.OfType<Grid>()
.FirstOrDefault(element => element.Tag is string && (string)element.Tag == "dragdrop");
if (mouseUpGrid != null)
{
Debug.WriteLine("MouseUp in " + mouseUpGrid.Name);
mouseUpGrid.Background = new SolidColorBrush(Colors.Red);
}
}
And you're done! This code should be able to handle complex scenarios like:
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0"
MouseLeftButtonUp="ContentPanel_MouseLeftButtonUp">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1"
Background="Green"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
<Grid x:Name="DummyGrid" Grid.Row="1">
<Grid x:Name="g2"
Background="Blue"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
</Grid>
</Grid>
One way to work around this is listening to the TouchFrame for a TouchAction.Up. You'll have to calculate the UIElement the ButtonUp cooresponds to using the TouchPoints' Position property as described here: http://forums.create.msdn.com/forums/p/98004/584465.aspx#584465
Another way is to capture the mouse in the ButtonDown UIElement. This will cause the ButtonUp to correctly fire, however the sender will be the original UIElement that caused the ButtonDown. You can track the elements the mouse moves through using MouseEnter and MouseLeave. The necessity for mouse capture is briefly touched on here: http://forums.create.msdn.com/forums/p/70785/431882.aspx
Last time I checked, my phone didn't have a mouse attached.
Use the Tap event instead of MouseLeftButtonUp. For more complicated gestures, use the Silverlight Toolkit GestureListener class.
Use MouseLeave event
http://vantsuyoshi.wordpress.com/2012/02/01/wp7-mouseleftbuttonup-not-fired-issue/