Close Flyout which contains a UserControl - windows-runtime

I am building a user control for a TextBox because I want it to have some special behaviour.
The control can be used in several contexts, including as a flyout for a button. When it is a flyout I want to close the flyout when the user presses the Enter key while editing text.
To achieve this, the control has a ParentButton dependency property which, if set, stores the button with the flyout, and the XAML for the parent page sets it in this case. The control has a KeyUp handler which detects the Enter key and, if ParentButton property is set, closes its flyout.
TextBoxUC.xaml
<UserControl
x:Class="TextBoxUCDemo.TextBoxUC"
...
xmlns:local="using:TextBoxUCDemo"
...>
<StackPanel Width="250">
<TextBox KeyUp="TextBox_KeyUp" Text="Hello" />
</StackPanel>
TextBoxUC.xaml.cs
public sealed partial class TextBoxUC : UserControl
{
public TextBoxUC() {
this.InitializeComponent();
}
internal static readonly DependencyProperty ParentButtonProperty =
DependencyProperty.Register("ParentButton", typeof(Button), typeof(TextBoxUC), new PropertyMetadata(null));
public Button ParentButton {
get { return ((Button)GetValue(ParentButtonProperty)); }
set { SetValue(ParentButtonProperty, value); }
}
private void TextBox_KeyUp(object sender, KeyRoutedEventArgs e) {
switch (e.Key) {
case VirtualKey.Enter:
// (Do something with the Text...)
// If this is a flyout from a button then hide the flyout.
if (ParentButton != null) { // Always null!
ParentButton.Flyout.Hide();
}
break;
default: return;
}
}
}
MainPage.xaml
<Page
x:Class="TextBoxUCDemo.MainPage"
...
xmlns:local="using:TextBoxUCDemo"
...>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="200,300">
<Button Name="flyoutTextBoxButton" Content="Edit">
<Button.Flyout>
<Flyout>
<local:TextBoxUC ParentButton="{Binding ElementName=flyoutTextBoxButton, Path=.}"/>
</Flyout>
</Button.Flyout>
</Button>
</Grid>
The problem is that the ParentButton is always null.
-- Edit --
I've narrowed the problem down to the binding to the element in the XAML. If I set the ParentButton from the code-behind of the MainPage, then it works.
In 'MainPage.xaml':
Loaded="Page_Loaded"
....
<local:TextBoxUC/>
In MainPage.xaml.cs
private void Page_Loaded(object sender, RoutedEventArgs e) {
textBoxUC.ParentButton = this.flyoutTextBoxButton;
}
Effect:
if (ParentButton != null) {
// Reaches here
}
So: THE PROBLEM is in the xaml ParentButton="{Binding ElementName=flyoutTextBoxButton, Path=.}", which compiles but has no effect.
If I add a changed event handler to the registration of the dependency property, then the handler is called when the ParentButton is set from the code-behind, but never called for the binding to the ElementName. The handler seems to be only useful for debugging purposes. I can't see that it is needed to make the property work.

Okay, how about this? I've used it in the past. Works fine.
[Microsoft.Xaml.Interactivity.TypeConstraint(typeof(Windows.UI.Xaml.Controls.TextBox))]
public class CloseFlyoutOnEnterBehavior : DependencyObject, IBehavior
{
public DependencyObject AssociatedObject { get; set; }
public void Attach(DependencyObject obj)
{
this.AssociatedObject = obj;
(obj as TextBox).KeyUp += TextBox_KeyUp;
}
void TextBox_KeyUp(object sender, KeyRoutedEventArgs e)
{
if (!e.Key.Equals(Windows.System.VirtualKey.Enter))
return;
var parent = this.AssociatedObject;
while (parent != null)
{
if (parent is FlyoutPresenter)
{
((parent as FlyoutPresenter).Parent as Popup).IsOpen = false;
return;
}
else
{
parent = VisualTreeHelper.GetParent(parent);
}
}
}
public void Detach()
{
(this.AssociatedObject as TextBox).KeyUp -= TextBox_KeyUp;
}
}
Use it like this:
<Button HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Click Me">
<Button.Flyout>
<Flyout Placement="Bottom">
<TextBox Width="200"
Header="Name"
PlaceholderText="Jerry Nixon">
<Interactivity:Interaction.Behaviors>
<local:CloseFlyoutOnEnterBehavior />
</Interactivity:Interaction.Behaviors>
</TextBox>
</Flyout>
</Button.Flyout>
</Button>
Learn more about behaviors here:
http://blog.jerrynixon.com/2013/10/everything-i-know-about-behaviors-in.html
And here (lesson 3):
http://blog.jerrynixon.com/2014/01/the-most-comprehensive-blend-for-visual.html
Best of luck!

You can add to your control normal property of type Action that will contain lambda expression.
You will set this property when creating control and then invoke it inside your control on EnterPressed event.
public class MyControll
{
public Action ActionAfterEnterPressed {get; set;}
private void HandleOnEnterPressed()
{
if(ActionAfterEnterPressed != null)
{
ActionAfterEnterPressed.Invoke();
}
}
}
somwhere where you create your control
...
MyControl c = new MyControl()
c.ActionAfterEnterPressed = CloseFlyuot;
....
private void CloseFlyuot()
{
_myFlyout.IsOpen = false;
}
This way you can set any action and invoke it when needed from inside of your control withou needing to bother with what action actually does.
Best of luck.

You're making it a dependency property. That's the first, right start. But until you handle the changed event, you aren't really going to get any value from it.
I discuss this more here:
http://blog.jerrynixon.com/2013/07/solved-two-way-binding-inside-user.html
Best of luck!

Related

Bind an Action to a property of a UserControl in XAML

I have a user control which has a button and a dependency property for the action the button is to execute. The page which contains the control sets the action in XAML.
MyUserControl.cs
A Button, and dependency property ButtonAction, of type Action. When the button is clicked it executes the ButtonAction.
MainPage.xaml.cs
Action Action1
Action Action2
MainPage.xaml
Present an instance of MyUserControl, with ButtonAction=Action1
The problem: The ButtonAction property is not assigned from the XAML
MyUserControl.cs
public sealed partial class MyUserControl : UserControl
{
public Action ButtonAction {
get { return (Action)GetValue(ButtonActionProperty); }
set { SetValue(ButtonActionProperty, value); }
}
public static readonly DependencyProperty ButtonActionProperty =
DependencyProperty.Register("ButtonAction", typeof(Action), typeof(MyUserControl), new PropertyMetadata(null,ButtonAction_PropertyChanged));
private static void ButtonAction_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
Debug.WriteLine("ButtonAction_PropertyChanged");
// Is not called!
}
public MyUserControl() {
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e) {
if (ButtonAction != null) {
// Never reaches here!
ButtonAction();
}
}
}
MyUserControl.xaml
<Grid>
<Button Click="Button_Click">Do The Attached Action!</Button>
</Grid>
MainPage.xaml.cs
Action Action1 = (
() => { Debug.WriteLine("Action1 called"); });
Action Action2 = (() => { Debug.WriteLine("Action2 called"); });
MainPage.xaml
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<local:MyUserControl x:Name="myUserControl" ButtonAction="{Binding Action1}"/>
</Grid>
It does work if in the code-behind for MainPage (MainPage.xaml.cs) I assign the action in the Loaded event.
private void Page_Loaded(object sender, RoutedEventArgs e) {
this.myUserControl.ButtonAction = Action1;
}
In this case the PropertyChanged callback in the user control is also called. (This handler is provided only for diagnostic purposes. I can't see how it can be used to support the property in practice).
The issue is in your data binding. The Action1 in ButtonAction="{Binding Action1}" should be a public property while you defined it as a private variable.
Also, you cannot just declare a normal property directly in the code behind like that. You will need either a dependency property, or more commonly, a public property inside a viewmodel which implements INotifyPropertyChanged.
If we go with the second approach, we will need to create a viewmodel class like the following with an Action1 property. Note the OnPropertyChanged stuff is just the standard way of implementing INotifyPropertyChanged.
public class ViewModel : INotifyPropertyChanged
{
private Action _action1;
public Action Action1
{
get { return _action1; }
set
{
_action1 = value;
OnPropertyChanged("Action1");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
And then you just need to assign this to the DataContext of your main page.
public MainPage()
{
this.InitializeComponent();
var vm = new ViewModel();
vm.Action1 = (() =>
{
Debug.WriteLine("Action1 called");
});
this.DataContext = vm;
}
With these two changes, your ButtonAction callback should be firing now. :)

How to add timer to change image for selected item in ListPicker

what would be the steps to add timer to change selected item's image in listpicker. Any suggestions? FYI, have never used ListPicker before. So i am finding it kind of hard to understand where to start and what to do.
You will need an ObservableCollection of your ImageSources and a DispatcherTimer to fire the events every TimeSpan of your choosing.
Here's some code to help you get started. You can modify it to do exactly what you want. It basically contains a ListPicker that has a collection of images as its ItemTemplate. Every one second the DispatchTimer fires and switches the selectedItem's Image between the 2 default images that are created in about every single WP8.0 application.
Make it a habit to use ObervableCollection when you want to display something to the user instead of a List, it will make your WP8 development life a lot easier.
XAML
<toolkit:ListPicker x:Name="my_listpicker" SelectionChanged="my_listpicker_SelectionChanged_1" Background="Black">
<toolkit:ListPicker.HeaderTemplate>
<DataTemplate/>
</toolkit:ListPicker.HeaderTemplate>
<toolkit:ListPicker.ItemTemplate>
<DataTemplate>
<StackPanel Background="Black">
<Image Source="{Binding ImageSource}" Height="200"></Image>
</StackPanel>
</DataTemplate>
</toolkit:ListPicker.ItemTemplate>
</toolkit:ListPicker>
C# Namespaces
using System.ComponentModel; // ObservableCollection
using System.Collections.ObjectModel; // INotifyPropertyChanged
using System.Windows.Threading; // Dispatch Timer
C# Model of your Images (pretty basic, but pay attention to the INotifyPropertyChanged
public class MyBindingImage : INotifyPropertyChanged
{
public MyBindingImage() { }
public MyBindingImage(string source)
{
this.ImageSource = source;
}
// Create the OnPropertyChanged method to raise the event
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
string image_source;
public String ImageSource {
get { return image_source; }
set
{
image_source = value;
OnPropertyChanged("ImageSource");
}
}
}
C# (Create the Timer and ObservableCollection and Set the ItemSource)
DispatcherTimer timer;
// Constructor
public MainPage()
{
// create our dispatch timer
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Tick += OnTimerTick;
InitializeComponent();
// create our list picker elements
ObservableCollection<MyBindingImage> my_image_list = new ObservableCollection<MyBindingImage>();
my_image_list.Add(new MyBindingImage("Assets/ApplicationIcon.png"));
my_image_list.Add(new MyBindingImage("Assets/AlignmentGrid.png"));
my_listpicker.ItemsSource = my_image_list;
}
C# Events (For the Timer & ListPicker SelectionChange)
// each time the selection has changd: stop the timer, then start it again
private void my_listpicker_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
if (timer != null)
{
timer.Stop();
timer.Start();
}
}
// if the timer is on, cycle the images of the selected item
private void OnTimerTick(object sender, EventArgs e)
{
try
{
MyBindingImage item = (MyBindingImage) my_listpicker.SelectedItem;
// cycle the selected image between to different images
if (item.ImageSource == "Assets/AlignmentGrid.png")
{
item.ImageSource = "Assets/ApplicationIcon.png";
}
else
{
item.ImageSource = "Assets/AlignmentGrid.png";
}
}
catch (Exception ex)
{
string error_message = ex.Message;
}
}
[APPLICATION SCREENSHOT]

WinRT FlipView like control in WP8

In my app I need to display a collection of Images exactly like in the Windows Phone 8 Photo App where you can swipe right and left between the images.
I've tried both the Panorama and Pivot control but both controls don't behave like WinRTs FlipView.
Panorama fits quite well but appears to have the "Right-Peek" Amount hardwired into the control. (please correct me if I'm wrong)
Pivot in turn shows blackness during swipes (finger still down) and only displays the next image when you release your finger and the control scrolls the next item into place.
Any suggestions?
Here is the customized FlipView control for WP8 like WINRT FlipView Control...
Step 1 : Add a new Usercontrol and name it as "FlipView.xaml"
Step 2 : Add following xaml in "FlipView.xaml"
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<ContentPresenter Name="contentPresenter"/>
<Button BorderThickness="0" Name="leftButton" FontSize="70" Margin="-25" HorizontalAlignment="Left" VerticalAlignment="Center" Content="<" Click="Button_Click"/>
<Button BorderThickness="0" Name="rightButton" FontSize="70" Margin="-25" HorizontalAlignment="Right" VerticalAlignment="Center" Content=">" Click="Button_Click_1"/>
</Grid>
Step 3 : Add the following code in the "FlipView.cs"
public partial class FlipView : UserControl
{
public FlipView()
{
InitializeComponent();
Datasource = new List<object>();
SelectedIndex = 0;
}
private IList Datasource;
public static readonly DependencyProperty ItemTemplateProperty =
DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(FlipView), new PropertyMetadata(default(DataTemplate)));
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set
{
SetValue(ItemTemplateProperty, value);
contentPresenter.ContentTemplate = value;
contentPresenter.Content = SelectedItem;
}
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IList), typeof(FlipView), new PropertyMetadata(default(IList)));
public IList ItemsSource
{
get { return (IList)GetValue(ItemsSourceProperty); }
set
{
SetValue(ItemsSourceProperty, value);
Datasource = value;
SelectedIndex = SelectedIndex;
}
}
public static readonly DependencyProperty SelectedIndexProperty =
DependencyProperty.Register("SelectedIndex", typeof(int), typeof(FlipView), new PropertyMetadata(default(int)));
public int SelectedIndex
{
get { return (int)GetValue(SelectedIndexProperty); }
set
{
SetValue(SelectedIndexProperty, value);
rightButton.Visibility = leftButton.Visibility = Visibility.Visible;
if (SelectedIndex == 0)
{
leftButton.Visibility = Visibility.Collapsed;
}
if (SelectedIndex + 1 == Datasource.Count)
{
rightButton.Visibility = Visibility.Collapsed;
SelectedItem = Datasource[SelectedIndex];
}
if (Datasource.Count > SelectedIndex + 1)
{
SelectedItem = Datasource[SelectedIndex];
}
}
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(FlipView), new PropertyMetadata(default(object)));
public object SelectedItem
{
get { return (object)GetValue(SelectedItemProperty); }
set
{
SetValue(SelectedItemProperty, value);
contentPresenter.Content = SelectedItem;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SelectedIndex--;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
SelectedIndex++;
}
}
Step 4 : Now at the mainpage, add the namespace to use the flipview Usercontrol
Example:
xmlns:FlipViewControl="clr-namespace:ImageFlip" (Note: It differs according to your Solution name).
Step 5 : Using the namespace, add the flipview control as follow as..
<Grid x:Name="LayoutRoot" Background="Transparent">
<FlipViewControl:FlipView Name="imgViewer">
<FlipViewControl:FlipView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Stretch="Fill"/>
</DataTemplate>
</FlipViewControl:FlipView.ItemTemplate>
</FlipViewControl:FlipView>
</Grid>
Step 6 : Add the following code in mainpage.cs
// Constructor
public MainPage()
{
InitializeComponent();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
imgViewer.ItemsSource = new List<string> { "/Images/1.jpg", "/Images/2.jpg", "/Images/3.jpg" };
}
Hope this will help.
Thanks
There is no direct equivalent to the FlipView in Windows Phone. The Panorama and Pivot controls have very different functionalities and are designed fro different purposes.
Telerik have a SlideView control which is very similar to the native control used by the photos app.
You can also get the Telerik controls free as part of the Nokia Premium Developer Program. (Worth investigating if you don't have a Dev Center subscription.)
I know it is not the same solution, but maybe you can tweak this coverflow example here... so that the images are not stacked but side by side?

using Gridview control inside a usercontrol

I am trying create UserControl with below requirements.
Usercontrol contains a gridview and in side gridview, I need to add a button element. So, the idea is :- if usercontrol is used in any other page by providing a collection to ItemSource then list of buttons should be generated and Button content value should be one of the property value of type present in Itemsource collection.
I am pretty newbie to windows store app programming. I am trying to expose the gridview ItemSources property by creating dependency property so that ObservableCollection of any type can be mapped and trying expose a dependency property to bind to button content property. but not able to achieve the same. I would really appreciate if you could point to a sample application doing the same.
Thanks a lot in advance.
here is a small sample (i hope that's what you wanna do)...
EDIT: I finally edited my answer to provide the property which takes the property path. IF ANYONE HAS ANOTHER SOLUTION FOR THIS QUESTION, PLEASE LET ME KNOW!
Add a dependency property for the binding path:
First we create a dummy model which provides the title for our buttons:
public class SampleModel
{
public string Title { get; set; }
}
Then, the usercontrol. The important thing here is the ItemsSource-Binding (ElementName = UserControl). Otherwise you'll bind to the UserControlItemsSource in the Parent-DataContext.
EDIT: The button has changed since my last answer!
<UserControl
x:Class="StackOverflow.ListUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:StackOverflow"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="SampleUserControl">
<Grid>
<ListView ItemsSource="{Binding UserControlItemsSource, ElementName=SampleUserControl}" Background="DeepSkyBlue" SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate>
<Button Loaded="FrameworkElement_OnLoaded"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</UserControl>
... and the usercontrol's code-behind including the UsercontrolItemsSource:
EDIT: i added the dependency property BindingPropertyPath and the FrameworkElement_OnLoaded method since my last answer.
public sealed partial class ListUserControl : UserControl
{
public ObservableCollection<SampleModel> UserControlItemsSource
{
get { return (ObservableCollection<SampleModel>)GetValue(UserControlItemsSourceProperty); }
set { SetValue(UserControlItemsSourceProperty, value); }
}
// Using a DependencyProperty as the backing store for UserControlItemsSource. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UserControlItemsSourceProperty =
DependencyProperty.Register("UserControlItemsSource", typeof(ObservableCollection<SampleModel>), typeof(ListUserControl), new PropertyMetadata(null));
public string BindingPropertyPath
{
get { return (string)GetValue(BindingPropertyPathProperty); }
set { SetValue(BindingPropertyPathProperty, value); }
}
// Using a DependencyProperty as the backing store for BindingPropertyPath. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BindingPropertyPathProperty =
DependencyProperty.Register("BindingPropertyPath", typeof(string), typeof(ListUserControl), new PropertyMetadata(string.Empty));
public ListUserControl()
{
this.InitializeComponent();
}
private void FrameworkElement_OnLoaded(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Binding contentBinding = new Binding();
contentBinding.Path = new PropertyPath(this.BindingPropertyPath);
button.SetBinding(Button.ContentProperty, contentBinding);
}
}
Now we add the usercontrol to our main page (ListPageHost):
EDIT: Set the new dependency property BindingPropertyPath to the name of the property of the ItemsSource that you wanna use for the button.
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="Add Item to ItemsSource" Click="ButtonBase_OnClick"></Button>
<local:ListUserControl Grid.Row="1" UserControlItemsSource="{Binding SampleCollection}" BindingPropertyPath="Title"/>
</Grid>
In the mainpage's code-behind, we declare our mainpage-viewmodel (ListPageHostViewModel):
public class ListPageHostViewModel
{
private readonly ObservableCollection<SampleModel> _sampleCollection = new ObservableCollection<SampleModel>();
public ObservableCollection<SampleModel> SampleCollection
{
get { return _sampleCollection; }
}
}
... and the MainPage's (ListPageHost) code behind:
public sealed partial class ListPageHost : Page
{
public ListPageHost()
{
this.InitializeComponent();
this.DataContext = new ListPageHostViewModel();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
var vm = this.DataContext as ListPageHostViewModel;
if (vm != null)
{
vm.SampleCollection.Add(new SampleModel() { Title = string.Format("new item {0}", DateTime.Now.Ticks)});
}
}
}
Hope that's what you're looking for. If you have any questions - let me know.
Regards, Alex

FlipView control is not available in Windows Phone 8 SDK

FlipView control is not available in Windows Phone 8 SDK, what are the alternate approach for implementing similar functionality?
There are a few options here. If you only want to display a fixed number of "pages", you can use the Panorama app. If you have a lot of pages to display, you'll want to use the pivot control.
If you absolutely have to re-implement the FlipView, you can do this by putting "left" and "right" buttons in the application bar. You'll need to build your own content area with a custom control. If you're going for a "cool" gesture-based navigation, you'll want to get the toolkit.
Here is the customized FlipView control for WP8 like WINRT FlipView Control...
Step 1 : Add a new Usercontrol and name it as "FlipView.xaml"
Step 2 : Add following xaml in "FlipView.xaml"
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<ContentPresenter Name="contentPresenter"/>
<Button BorderThickness="0" Name="leftButton" FontSize="70" Margin="-25" HorizontalAlignment="Left" VerticalAlignment="Center" Content="<" Click="Button_Click"/>
<Button BorderThickness="0" Name="rightButton" FontSize="70" Margin="-25" HorizontalAlignment="Right" VerticalAlignment="Center" Content=">" Click="Button_Click_1"/>
</Grid>
Step 3 : Add the following code in the "FlipView.cs"
public partial class FlipView : UserControl
{
public FlipView()
{
InitializeComponent();
Datasource = new List<object>();
SelectedIndex = 0;
}
private IList Datasource;
public static readonly DependencyProperty ItemTemplateProperty =
DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(FlipView), new PropertyMetadata(default(DataTemplate)));
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set
{
SetValue(ItemTemplateProperty, value);
contentPresenter.ContentTemplate = value;
contentPresenter.Content = SelectedItem;
}
}
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IList), typeof(FlipView), new PropertyMetadata(default(IList)));
public IList ItemsSource
{
get { return (IList)GetValue(ItemsSourceProperty); }
set
{
SetValue(ItemsSourceProperty, value);
Datasource = value;
SelectedIndex = SelectedIndex;
}
}
public static readonly DependencyProperty SelectedIndexProperty =
DependencyProperty.Register("SelectedIndex", typeof(int), typeof(FlipView), new PropertyMetadata(default(int)));
public int SelectedIndex
{
get { return (int)GetValue(SelectedIndexProperty); }
set
{
SetValue(SelectedIndexProperty, value);
rightButton.Visibility = leftButton.Visibility = Visibility.Visible;
if (SelectedIndex == 0)
{
leftButton.Visibility = Visibility.Collapsed;
}
if (SelectedIndex + 1 == Datasource.Count)
{
rightButton.Visibility = Visibility.Collapsed;
SelectedItem = Datasource[SelectedIndex];
}
if (Datasource.Count > SelectedIndex + 1)
{
SelectedItem = Datasource[SelectedIndex];
}
}
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(FlipView), new PropertyMetadata(default(object)));
public object SelectedItem
{
get { return (object)GetValue(SelectedItemProperty); }
set
{
SetValue(SelectedItemProperty, value);
contentPresenter.Content = SelectedItem;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SelectedIndex--;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
SelectedIndex++;
}
}
Step 4 : Now at the mainpage, add the namespace to use the flipview Usercontrol
Example:
xmlns:FlipViewControl="clr-namespace:ImageFlip" (Note: It differs according to your Solution name).
Step 5 : Using the namespace, add the flipview control as follow as..
<Grid x:Name="LayoutRoot" Background="Transparent">
<FlipViewControl:FlipView Name="imgViewer">
<FlipViewControl:FlipView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Stretch="Fill"/>
</DataTemplate>
</FlipViewControl:FlipView.ItemTemplate>
</FlipViewControl:FlipView>
</Grid>
Step 6 : Add the following code in mainpage.cs
// Constructor
public MainPage()
{
InitializeComponent();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
imgViewer.ItemsSource = new List<string> { "/Images/1.jpg", "/Images/2.jpg", "/Images/3.jpg" };
}
Hope this will help.
Thanks
I've used the FlipView version from the Windows Phone Toolkit.
If you have the NuGet extension enabled, getting the Toolkit is very easy: right click your project in Solution Exporer -> Manage NuGet Packages -> make sure the Online is selected (in the left column) -> type in the Search field (right column) "toolkit" -> Click the Install button on the appropriate package.
Using the FlipView from code behind is as simple as:
Microsoft.Phone.Controls.FlipView flipView = new Microsoft.Phone.Controls.FlipView();
flipView.ItemSource = myItemSource;
flipView.ItemTemplate = myItemTemplate;
I preferred to use this approach because this FrameworkElement responds well to the swipe gesture.