Frame navigation issue while using Drawer Layout in windows phone 8.1 - c#

I am developing a Windows Phone App 8.1 using a third party DrawerLayout.
My problem is when I have design the page using draweralayout. I need to pass the same layout to each other pages in my application. but when i use bold Frame.navigate(typeof(Page1)); the application is crashed.
I am unable to debug the problem.
please help!!!
My Xaml Code is
<Grid x:Name="Rootlayout">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- title bar-->
<Grid x:Name="TitleBar" Height="50" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="SkyBlue">
<Image Source="/Assets/fs-logo.png" Height="50" HorizontalAlignment="Left" Margin="10,0,0,0"/>
</Grid>
<!--Drawer Layout-->
<drawer:DrawerLayout x:Name="DrawerLayout" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<!--Main Layout-->
<Grid x:Name="mainLayout" Background="White" >
<ScrollViewer>
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="mainImage" Grid.Row="0" Source="{Binding }"></Image>
<GridView x:Name="grdView" Grid.Row="1" ItemsSource="{Binding }" ItemContainerStyle="{StaticResource GridViewItemContainer}" Tapped="grdView_Tapped" >
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Blue">
<Grid Height="{Binding Size}"
Width="{Binding Size}">
<Image Height="120" Width="150" Source="{Binding sImageURL}" Stretch="Fill">
</Image>
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Bottom" Foreground="Black" FontSize="18"/>
</Grid>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"></ItemsWrapGrid>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</Grid>
</ScrollViewer>
</Grid>
<!--Drawer Layout-->
<Grid x:Name="listFragment" FlowDirection="LeftToRight" >
<ListView x:Name="listItem" SelectionChanged="listItem_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="20" Foreground="Black" Margin="10" VerticalAlignment="Center" HorizontalAlignment="Left"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</drawer:DrawerLayout>
<Image Grid.Row="1" Grid.Column="0" Height="50" Width="50" Source="/Assets/appbar.right.png" Tapped="chevlon_Tapped">
</Image>
</Grid>
My MainPage.cs
public sealed partial class MainPage : Page
{
private NavigationHelper navigationHelper;
private ObservableDictionary defaultViewModel = new ObservableDictionary();
List<Services.Company> companyData;
List<Services.Category> categoryData;
public MainPage()
{
this.InitializeComponent();
Loaded += MainPage_Loaded;
this.navigationHelper = new NavigationHelper(this);
this.navigationHelper.LoadState += this.NavigationHelper_LoadState;
this.navigationHelper.SaveState += this.NavigationHelper_SaveState;
this.NavigationCacheMode = NavigationCacheMode.Required;
}
async void MainPage_Loaded(object sender, RoutedEventArgs e)
{
await Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync();
// SetGridViewItemSize();
//throw new NotImplementedException();
}
/// <summary>
/// Gets the <see cref="NavigationHelper"/> associated with this <see cref="Page"/>.
/// </summary>
public NavigationHelper NavigationHelper
{
get { return this.navigationHelper; }
}
/// <summary>
/// Gets the view model for this <see cref="Page"/>.
/// This can be changed to a strongly typed view model.
/// </summary>
public ObservableDictionary DefaultViewModel
{
get { return this.defaultViewModel; }
}
private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
if (e.PageState != null)
{
// this.DefaultViewModel["MainPage"] = (MainPage)e.PageState["MainPage"];
// Restore scroll offset
var index = (int)e.PageState["FirstVisibleItemIndex"];
var container = grdView.ContainerFromIndex(index);
grdView.ScrollIntoView(container);
}
else
{
//Load Data for the First time
DrawerLayout.InitializeDrawerLayout();
var company = await Services.CompCatInfo.GetCompaniesAsync(App.compId);
companyData = company.ToList();
if (companyData.Count > 0)
{
mainImage.Source = new BitmapImage(new Uri(companyData.ElementAt(0).LogoImgUrl, UriKind.Absolute));
}
var category = await Services.CompCatInfo.GetCategoriesAsync(App.compId);
categoryData = category.ToList();
SetGridViewItemSize();
if (categoryData.Count > 0)
{
grdView.ItemsSource = categoryData;
}
}
}
private void NavigationHelper_SaveState(object sender, SaveStateEventArgs e)
{
var isp = (ItemsWrapGrid)grdView.ItemsPanelRoot;
int firstVisibleItem = isp.FirstVisibleIndex;
e.PageState["FirstVisibleItemIndex"] = firstVisibleItem;
// e.PageState["HomePage"] = this.Frame.CurrentSourcePageType;
// This must be serializable according to the SuspensionManager
//e.PageState["MainPage"] = this.DefaultViewModel["MainPage"];
}
private void SetGridViewItemSize()
{
//var viewModel = (DataContext as ViewModel1);
var width = Math.Truncate((grdView.ActualWidth - 10));
var height = Math.Truncate((grdView.ActualHeight - 10));
// total left + right margin for each tile (ItemContainerStyle)
var margin = 10;
var twoColumnGridPortrait = (width / 2) - margin;
// var threeColumnGridPortrait = (width / 3) - margin;
var twoColumnGridLandscape = (height / 2) - margin;
var threeColumnGridLandscape = (height / 3) - margin;
double portrait;
double landscape;
portrait = twoColumnGridPortrait;
landscape = threeColumnGridLandscape;
Application.Current.Resources["GridViewItemPortrait"] = Math.Round(portrait, 2);
Application.Current.Resources["GridViewItemLandscape"] = Math.Round(landscape, 2);
if (DisplayInformation.GetForCurrentView().CurrentOrientation == DisplayOrientations.Portrait)
{
Measure((double)Application.Current.Resources["GridViewItemPortrait"]);
}
else
{
Measure((double)Application.Current.Resources["GridViewItemLandscape"]);
}
// throw new NotImplementedException();
}
private void Measure(double size)
{
for (int i = 0; i < categoryData.Count; i++)
{
var item = categoryData[i];
item.Size = size;
}
//throw new NotImplementedException();
}
#region NavigationHelper registration
/// <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.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
//if (e.NavigationMode == NavigationMode.New)
//{
// DrawerLayout.InitializeDrawerLayout();
// var company = await Services.CompCatInfo.GetCompaniesAsync(App.compId);
// companyData = company.ToList();
// if (companyData.Count > 0)
// {
// mainImage.Source = new BitmapImage(new Uri(companyData.ElementAt(0).LogoImgUrl, UriKind.Absolute));
// }
// var category = await Services.CompCatInfo.GetCategoriesAsync(App.compId);
// categoryData = category.ToList();
// SetGridViewItemSize();
// grdView.ItemsSource = categoryData;
//}
//else
//{
// // this.Frame.Content = e.Content;
//}
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedFrom(e);
}
#endregion
private void chevlon_Tapped(object sender, TappedRoutedEventArgs e)
{
string[] list = new string[] { "Services","Solutions","Technologies","About Us"};
listItem.ItemsSource = list.ToList();
if(DrawerLayout.IsDrawerOpen)
{
DrawerLayout.CloseDrawer();
}
else
{
DrawerLayout.OpenDrawer();
}
}
private void listItem_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (listItem.SelectedItem != null)
{
var selecteditem = listItem.SelectedValue as string;
// DetailsTxtBlck.Text = "SelectedItem is: " + selecteditem;
DrawerLayout.CloseDrawer();
listItem.SelectedItem = null;
}
}
private void grdView_Tapped(object sender, TappedRoutedEventArgs e)
{
DrawerLayout.CloseDrawer();
if(e.OriginalSource.GetType().ToString()=="Windows.UI.Xaml.Controls.Image"||e.OriginalSource.GetType().ToString()=="Windows.UI.Xaml.Controls.TextBlock")
{
var catObj = (sender as GridView).SelectedItem as Services.Category;
////Frame rootFrame = Window.Current.Content as Frame;
////rootFrame.Navigate(typeof(Page2),catObj);
Frame.Navigate(typeof(Page2),catObj);
}
}
}

You can navigate by this way
CoreDispatcher dispatcher = CoreWindow.GetForCurrentThread().Dispatcher;
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
(Window.Current.Content as Frame).Navigate(typeof(Page name));
});

Related

Access InkToolbar placed in parent element from programmatically generated child elements

I have a UserControl which contains a InkToolbar. In this control I'm generating another set of UserControls based on user input. In each of those programmatically generated controls, contains a InkCanvas.
This is the parent UserControl & the code behind.
Main.xaml
<UserControl
x:Class="uwp.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:uwp_mvvm"
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">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<InkToolbar x:Name="InkToolbar" Background="Black" Margin="10 0 0 0" VerticalAlignment="Center"/>
</StackPanel>
<ScrollViewer ZoomMode="Enabled" Background="DarkGray" x:Name="ScrollViewer" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" MinZoomFactor="0.25" Width="Auto" Height="Auto" MaxZoomFactor="4" Grid.Row="1">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<ItemsControl x:Name="PagesItemsControl" ItemsSource="{x:Bind Pages, Mode=OneWay}" HorizontalAlignment="Center" VerticalAlignment="Top">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:TestControl x:Name="TestControl" Page="{Binding}" Margin="4 4" InkToolbarControl="{Binding Path=InkToolbar, ElementName=InkToolbar}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
</Grid>
</UserControl>
Main.xaml.cs
public sealed partial class MainViewer : UserControl
{
public MainViewer()
{
this.InitializeComponent();
}
private void EventTriggerChanged(object sender, PropertyChangedEventArgs e)
{
var trigger = sender as EventTriggerTestControl;
if (trigger != null)
RaiseChanged(e.PropertyName);
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaiseChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propName));
}
private PdfDocument pdfDocument = null;
private string password = string.Empty;
private ObservableCollection<PdfPage> pages = new ObservableCollection<PdfPage>();
public string Password
{
private get { return password; }
set { if (value != password) { password = value; } }
}
public ObservableCollection<PdfPage> Pages
{
get { return pages; }
set { if (value != pages) { pages = value; } }
}
public StorageFile File
{
get { return (StorageFile)GetValue(FileProperty); }
set { SetValue(FileProperty, value); }
}
public static readonly DependencyProperty FileProperty =
DependencyProperty.Register(nameof(File), typeof(StorageFile), typeof(MainViewer), new PropertyMetadata(null, new PropertyChangedCallback(OnDocumentChanged)));
private static void OnDocumentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (object.Equals(e.NewValue, e.OldValue) || e.NewValue is null)
return;
d.RegisterPropertyChangedCallback(FileProperty, CaptureDocument);
}
private async static void CaptureDocument(DependencyObject sender, DependencyProperty dp) => await (sender as MainViewer).OpenFileAsync(sender.GetValue(dp) as StorageFile);
private async Task OpenFileAsync(StorageFile file)
{
try
{
if (file == null)
throw new ArgumentNullException(nameof(file));
var files = await ApplicationData.Current.LocalFolder.GetFilesAsync(CommonFileQuery.OrderByName);
if (files.Where(x => x.Name == file.Name).ToList().Count == 0)
await file.CopyAsync(ApplicationData.Current.LocalFolder, file.Name, NameCollisionOption.ReplaceExisting);
file = await ApplicationData.Current.LocalFolder.GetFileAsync(file.Name);
pdfDocument = new PdfDocument(file.Path, Password);
pdfDocument.Pages.ToList().ForEach(x => Pages.Add(x));
}
catch (Exception ex) { throw ex; }
}
}
I want to use the InkToolbar which is in the parent control inside the TestControl
TestControl.xaml
<UserControl
x:Class="uwp.TestControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="using:uwp_mvvm.ViewModels" xmlns:converter="using:uwp_mvvm"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
</UserControl.Resources>
<Grid x:Name="Viewport" VerticalAlignment="Top" HorizontalAlignment="Center">
<Border x:Name="ViewportBorder" Background="White" BorderThickness="2, 2, 2, 2" BorderBrush="#FF353334" />
<Image x:Name="Image" Margin="0" UseLayoutRounding="True" ManipulationMode="Scale"/>
<Canvas x:Name="SelectionCanvas" CompositeMode="MinBlend" Opacity="1" />
<InkCanvas x:Name="InkCanvas" />
</Grid>
</UserControl>
TastControl.xaml.cs
public sealed partial class TestControl : UserControl
{
private const float DPI = 256;
public PdfPage Page
{
get { return (PdfPage)GetValue(PageProperty); }
set { SetValue(PageProperty, value); }
}
public static readonly DependencyProperty PageProperty =
DependencyProperty.Register(nameof(Page), typeof(PdfPage), typeof(TestControl), new PropertyMetadata(null, new PropertyChangedCallback(OnPageChanged)));
private static void OnPageChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (object.Equals(e.NewValue, e.OldValue) || e.NewValue is null)
return;
d.RegisterPropertyChangedCallback(PageProperty, CapturePage);
}
private static void CapturePage(DependencyObject sender, DependencyProperty dp) => (sender as TestControl).RenderPage(sender.GetValue(dp) as PdfPage);
public InkToolbar InkToolbarControl
{
get { return (InkToolbar)GetValue(InkToolbarControlProperty); }
set { SetValue(InkToolbarControlProperty, value); }
}
public static readonly DependencyProperty InkToolbarControlProperty =
DependencyProperty.Register(nameof(InkToolbarControl), typeof(InkToolbar), typeof(TestControl), new PropertyMetadata(null));
public TestControl()
{
this.InitializeComponent();
ConfigureInkCanvas();
}
private void ConfigureInkCanvas()
{
InkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen | CoreInputDeviceTypes.Touch;
InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.None;
InkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(
new InkDrawingAttributes
{
IgnorePressure = false,
FitToCurve = true,
Color = Colors.Black,
PenTip = PenTipShape.Circle
});
InkCanvas.InkPresenter.UnprocessedInput.PointerEntered -= InkCanvasUnprocessedInputPointerEntered;
InkCanvas.InkPresenter.UnprocessedInput.PointerEntered += InkCanvasUnprocessedInputPointerEntered;
InkCanvas.InkPresenter.UnprocessedInput.PointerExited -= InkCanvasUnprocessedInputPointerExited;
InkCanvas.InkPresenter.UnprocessedInput.PointerExited += InkCanvasUnprocessedInputPointerExited;
}
private void InkCanvasUnprocessedInputPointerExited(InkUnprocessedInput sender, PointerEventArgs args)
{
//InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Inking;
//InkToolbarControl.TargetInkCanvas = InkCanvas;
}
private void InkCanvasUnprocessedInputPointerEntered(InkUnprocessedInput sender, PointerEventArgs args)
{
//InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.None;
//InkToolbarControl.TargetInkCanvas = null;
}
private void RenderPage(PdfPage page, float dpi = DPI)
{
if (page is null)
return;
this.DataContext = page;
var width = (DataContext as PdfPage).Width;
var height = (DataContext as PdfPage).Height;
var writableBitmap = new WriteableBitmap((int)(width / 72f * dpi), (int)(height / 72f * dpi));
(DataContext as PdfPage).Render(writableBitmap, PageOrientations.Normal, RenderingFlags.Annotations);
Image.Width = width;
Image.Height = height;
Image.Source = writableBitmap;
SelectionCanvas.Width = width;
SelectionCanvas.Height = height;
InkCanvas.Width = width;
InkCanvas.Height = height;
Canvas.SetZIndex(Image, 0);
ConfigureInkCanvas();
}
}
I tried to use a DependencyProperty to send the InkToolbar to the TestControl but it didn't seem to work.
Could someone please help me with this? I'm not sure whether it is possible to set the TargetInkCanvas like this also. So, if there is a better approach for this any suggestions are also appreciated.
Any help is much appreciated. Thanks.
Access InkToolbar placed in parent element from programmatically generated child elements
Above solution that use DependencyProperty to pass parent InkToolBar is correct. However you bind wrong value for InkToolbarControl property.
Please bind ElementName without path directly.
<local:TestControl
x:Name="TestControl"
Margin="4,4"
InkToolbarControl="{Binding ElementName=InkToolbar}" />
Then update InkCanvasUnprocessedInputPointerExited and InkCanvasUnprocessedInputPointerEntered process logic.
private void InkCanvasUnprocessedInputPointerExited(InkUnprocessedInput sender, PointerEventArgs args)
{
InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.Inking;
InkToolbarControl.TargetInkCanvas = null;
}
private void InkCanvasUnprocessedInputPointerEntered(InkUnprocessedInput sender, PointerEventArgs args)
{
InkCanvas.InkPresenter.InputProcessingConfiguration.Mode = InkInputProcessingMode.None;
InkToolbarControl.TargetInkCanvas = InkCanvas;
}

WPF: TextBlock AutomationProperties.HelpText change

I want to create an accessible application. I want to show pdf files in TextBlock page by page but when I change the CurrentPage properties on EbookViewerViewModel the NVDA Screen Reader doesn't read It the text again. I thought if I set focus again the Screen Reader will read it, but doesn't. Can I solve this problem somehow?
The EbookViewerWindow.xaml contains this:
<Window x:Class="myproj.EbookViewerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:myproj"
mc:Ignorable="d"
Title="AEBCA - Könyv megjelenítő" Height="300" Width="300" Closed="Window_Closed" WindowStartupLocation="CenterScreen" KeyDown="Window_KeyDown">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" x:Name="AuthorTB" Text="{Binding Author}" AutomationProperties.Name="A könyv szerzője" AutomationProperties.HelpText="{Binding Author}" Focusable="True"></TextBlock>
<TextBlock Grid.Row="0" Grid.Column="1" x:Name="BookNameTB" Text="{Binding BookName}" AutomationProperties.Name="A könyv címe" AutomationProperties.HelpText="{Binding BookName}" Focusable="True"></TextBlock>
<DockPanel Grid.Row="1" Grid.ColumnSpan="2">
<TextBlock x:Name="CurrentPageTB" Text="{Binding CurrentPage}" AutomationProperties.Name="A könyv tartalma" AutomationProperties.HelpText="{Binding CurrentPage}" Focusable="True"></TextBlock>
<Label x:Name="help"></Label>
</DockPanel>
</Grid>
In the code behind I do this:
public partial class EbookViewerWindow : Window
{
EbookViewerViewModel vm;
int index = 0;
PdfReader pdfReader;
public EbookViewerWindow()
{
InitializeComponent();
vm = new EbookViewerViewModel();
DataContext = vm;
vm.Author = "Antoine de Saint-Exupéry";
vm.BookName = "A Kis Herceg";
AuthorTB.Focus();
string fileName = #"d:\pdf.pdf";
if (File.Exists(fileName))
{
pdfReader = new PdfReader(fileName);
NextPage(pdfReader);
}
}
private void Window_Closed(object sender, EventArgs e)
{
MainWindow mainWindow = new MainWindow();
mainWindow.Show();
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if(e.Key == Key.Right)
{
NextPage(pdfReader);
CurrentPageTB.Focus();
e.Handled = true;
}
if(e.Key == Key.Left)
{
PreviousPage(pdfReader);
CurrentPageTB.Focus();
e.Handled = true;
}
}
private void NextPage(PdfReader pdfReader)
{
index++;
int pages = pdfReader.NumberOfPages;
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
string currentText = index.ToString() + ". oldal \n";
string temp = PdfTextExtractor.GetTextFromPage(pdfReader, index, strategy);
currentText += temp;
vm.CurrentPage = currentText;
}
private void PerviousPage(PdfReader pdfReader)
{
index--;
int pages = pdfReader.NumberOfPages;
ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
string currentText = index.ToString() + ". oldal \n";
string temp = PdfTextExtractor.GetTextFromPage(pdfReader, index, strategy);
currentText += temp;
vm.CurrentPage = currentText;
}
}
}
My EbookViewerViewModel:
public class EbookViewerViewModel : BaseViewModel
{
private string currentPage;
public string BookName { get; set; }
public string Author { get; set; }
public string CurrentPage { get { return currentPage; } set { currentPage = value; OnPropertyChanged(); } }
}
I found answer here:
How do I make screen readers read my WPF message similarly to how they read Win32 MessageBox?
<DockPanel Grid.Row="1" Grid.ColumnSpan="2">
<TextBlock x:Name="CurrentPageTB" Text="{Binding CurrentPage}" Focusable="True">
<Run AutomationProperties.Name="A könyv tartalma" AutomationProperties.HelpText="{Binding CurrentPage}"></Run>
</TextBlock>
</DockPanel>

How can I get nice animations in a ListView when an ObservableCollection gets sorted on UWP?

I cant get nice reorder animation in ListView - also tried overriding all the various internal transitions via the <Transitions><TransitionsCollection>... property. Nothing. Tried using simple .Insert/.Remove and .Move and neither works nicely.
Insert/Remove has animation for the items that happen to have been pushed around and .Move acts like a Reset on the collection.
The following code in MainPage:
public sealed partial class MainPage : Page
{
private ObservableCollection<Holder> Items = new ObservableCollection<Holder>(Enumerable.Range(0, 10).Select(x => new Holder(x)));
public MainPage()
{
this.InitializeComponent();
Items.CollectionChanged += Items_CollectionChanged;
}
private void Items_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
}
private Random _random = new Random();
private bool asc = true;
private void Button_Click(object sender, RoutedEventArgs e)
{
IList<Holder> temp;
//var temp = Items.Skip(1).Union(Items.Take(1)).ToList();
// var temp = new Holder[] { Items.ElementAt(Items.Count - 1) }.Union(Items.Take(Items.Count - 1)).ToList();
temp = Items.OrderBy(x => _random.NextDouble()).ToList();
// temp = asc ? Items.OrderBy(x => x.I).ToList() : Items.OrderByDescending(x => x.I).ToList();
asc = !asc;
for (int i = 0; i < temp.Count; i++)
{
if (Items[i] != temp[i])
{
// When using Move, no animation occurs at all. When using Remove/Insert, there's partial
// animation for the items that happened to stay at the same place.
//Items.Move(Items.IndexOf(temp[i]), i);
Items.Remove(temp[i]);
Items.Insert(i, new Holder(temp[i].I));
}
}
}
}
public class Holder
{
public Holder(int i)
{
I = i;
}
public string Name => "Hey hey hey " + I.ToString();
public int I { get; private set; }
public override bool Equals(object obj)
{
return ((Holder)obj).I == I;
}
public override int GetHashCode()
{
return I.GetHashCode();
}
}
With the following XAML:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Content="Mix" Click="Button_Click" Grid.Row="1"></Button>
<ListView ItemsSource="{x:Bind Items}" >
<ListView.ItemTemplate>
<DataTemplate>
<Border BorderThickness="3" BorderBrush="Blue">
<TextBlock Text="{Binding Name}" Margin="20"/>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>

read the control that you touched in a longlistselector

I have a longlistselector to show a gallery of the projects that I have in my app. Every item of the longlistselector have an image of the project, the name and an image to share it in social networks. The problem is that I need know when I touch the share image to leave to a different page that allow us to share it. This is the gallery longlistselector xaml:
<phone:LongListSelector x:Name="GaleryLongListSelector" SelectionChanged="GaleryLongListSelector_SelectionChanged" Margin="0,0,0,15">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid Margin="-20,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Margin="12,2,0,4" Height="100" toolkit:TiltEffect.IsTiltEnabled="True" Grid.Column="0">
<Image Width="80" RenderTransformOrigin="0.5,0.5" Height="80" Source="{Binding ThumbImage}">
<Image.RenderTransform>
<RotateTransform Angle="90"/>
</Image.RenderTransform>
</Image>
<!--<StackPanel Orientation="Vertical">-->
<TextBlock x:Name="txtProjectName" Margin="20,0" VerticalAlignment="Center" Text="{Binding Name}" Style="{StaticResource PhoneTextNormalStyle}" FontSize="{StaticResource PhoneFontSizeExtraLarge}" />
<!--<ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible">
<TextBlock x:Name="txtProjectDescript" Text="Aqui iria una descripcion muy larga del faldksjfjkldjfkldajsfkljaslfkjasldfjlasdjfkl" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="{StaticResource PhoneFontSizeLarge}"/>
</ScrollViewer>-->
<!--</StackPanel>-->
</StackPanel>
<Image Source="/Images/share.png" Height="50" Tap="Image_Tap" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right"/>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="True" x:Name="ContextMenu">
<toolkit:MenuItem Header="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.MainPagePanoramaItemGalleryContextMenuDelete}" Click="Delete_Click"/>
<toolkit:MenuItem Header="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.MainPagePanoramaItemGalleryContextMenuRename}" Click="Rename_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Grid>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
I read the item selected in a "SelectionChanged" event like this:
private void GaleryLongListSelector_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
if (GaleryLongListSelector != null && GaleryLongListSelector.SelectedItem != null)
{
var selectedItem = (Project)GaleryLongListSelector.SelectedItem;
var id = selectedItem.ID;
NavigationService.Navigate(new Uri("/ProjectViewPage.xaml?projectID=" + id.ToString(), UriKind.Relative));
}
}
I can use the tap event of the image but using this method I can't find the index of the longlistselector item touched.
Thanks everyone!!
Use the IndexOf() method on your ItemsSource colelction..
var dataItems = GaleryLongListSelector.ItemsSource as List<Project>;
var selectedItem = (Project)GaleryLongListSelector.SelectedItem;
var indexOfSelectedItem = dataItems.IndexOf(selectedItem)
public partial class MainPage : PhoneApplicationPage
{
public Product selectedItemData;
// Constructor
public MainPage()
{
InitializeComponent();
lsttest.ItemsSource = App.lstp;
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
private void Add_Click_1(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri(#"/Page2.xaml", UriKind.Relative));
}
private void lsttest_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
selectedItemData = e.AddedItems[0] as Product;
NavigationService.Navigate(new Uri(#"/Page2.xaml", UriKind.Relative));
}
// Sample code for building a localized ApplicationBar
//private void BuildLocalizedApplicationBar()
//{
// // Set the page's ApplicationBar to a new instance of ApplicationBar.
// ApplicationBar = new ApplicationBar();
// // Create a new button and set the text value to the localized string from AppResources.
// ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative));
// appBarButton.Text = AppResources.AppBarButtonText;
// ApplicationBar.Buttons.Add(appBarButton);
// // Create a new menu item with the localized string from AppResources.
// ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText);
// ApplicationBar.MenuItems.Add(appBarMenuItem);
//}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Page2 destinationpage = e.Content as Page2;
if (destinationpage != null)
{
// Change property of destination page
destinationpage.GetProduct = selectedItemData;
}
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
//Page2 destinationpage = e.Content as Page2;
//if (destinationpage != null)
//{
// // Change property of destination page
// destinationpage.GetProduct = selectedItemData;
//}
}
}
public partial class Page2 : PhoneApplicationPage
{
public Product GetProduct { get; set; }
public Page2()
{
InitializeComponent();
}
private void Add_Click_1(object sender, RoutedEventArgs e)
{
Product p2 = stkProduct.DataContext as Product;
// p2.Name = txtName1.Text;
if (string.IsNullOrEmpty(p2.ID))
{
p2.ID = DateTime.Now.ToString("yyyyMMddhhmmsstt");
App.lstp.Add(p2);
}
else
{
int index = App.lstp.IndexOf(p2);
App.lstp.Remove(GetProduct);
App.lstp.Insert(index, p2);
}
NavigationService.Navigate(new Uri(#"/MainPage.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (GetProduct == null)
{
GetProduct = new Product();
ApplicationBarIconButton btn = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
btn.Text = "Add";
btn.IconUri = new Uri("/Assets/check.png", UriKind.Relative);
}
else
{
ApplicationBarIconButton btn = (ApplicationBarIconButton)ApplicationBar.Buttons[0];
btn.Text = "save";
btn.IconUri = new Uri("/Assets/save.png", UriKind.Relative);
}
stkProduct.DataContext = GetProduct;
}
private void ApplicationBarIconButton_Click_1(object sender, EventArgs e)
{
Product p2 = stkProduct.DataContext as Product;
// p2.Name = txtName1.Text;
if (string.IsNullOrEmpty(p2.ID))
{
p2.ID = DateTime.Now.ToString("yyyyMMddhhmmsstt");
App.lstp.Add(p2);
}
else
{
int index = App.lstp.IndexOf(p2);
App.lstp.Remove(GetProduct);
App.lstp.Insert(index, p2);
}
NavigationService.Navigate(new Uri(#"/MainPage.xaml", UriKind.Relative));
}
}
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="lsttest" SelectionChanged="lsttest_SelectionChanged_1">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox x:Name="txtname" Text="{Binding Name}"></TextBox>
<TextBox x:Name="txtID" Text="{Binding ID}" Visibility="Collapsed"></TextBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
using System;
using System.IO.IsolatedStorage;
namespace MobileCartWL.HelperClasses
{
public class Helper
{
#region appSettings
public static IsolatedStorageSettings appSettings;
#endregion
//This function is used to insert Key,Value pair information in the Isolated Storage memory
#region InsertDetailInMemory
public static void InsertDetailInMemory(string key, object value)
{
try
{
appSettings = IsolatedStorageSettings.ApplicationSettings;
if (!appSettings.Contains(key))
appSettings.Add(key, value);
else
appSettings[key] = value;
appSettings.Save();
}
catch (Exception) { }
}
#endregion
//This function is used to remove Key,Value pair information from the Isolated Storage memory
#region RemoveDetailInMemory
public static void RemoveDetailInMemory(string key)
{
appSettings = IsolatedStorageSettings.ApplicationSettings;
if (appSettings.Contains(key))
{
appSettings.Remove(key);
appSettings.Save();
}
}
#endregion
//This function is used to check the existing of Key,Value pair information in the Isolated Storage memory
#region IsExistKeyInMemory
/// <summary>
/// Check if Specified Key Is Exists or not
/// </summary>
/// <param name="key">Key</param>
/// <returns>true if it exists otherwise return false</returns>
public static bool IsExistKeyInMemory(string key)
{
appSettings = IsolatedStorageSettings.ApplicationSettings;
if (appSettings.Contains(key))
{
return true;
}
else
{
return false;
}
}
#endregion
//This function is used to get Key,Value pair information from the Isolated Storage memory
#region GetDetailFromMemory
/// <summary>
/// Get value from memory of Specified Key
/// </summary>
/// <param name="key">Key</param>
/// <returns>value as Object of Specified Key</returns>
public static object GetDetailFromMemory(string key)
{
object value = string.Empty;
try
{
appSettings = IsolatedStorageSettings.ApplicationSettings;
if (appSettings.Contains(key))
{
value = appSettings[key];
}
return value;
}
catch (Exception)
{
return value;
}
}
#endregion
}
}

How do I access the property of an item in a ListBox in XAML?

I have a listbox of "SmartText" items, which are basically link objects with properties for a title, description, and a url. I'm trying to make the Grid panel in the XAML tappable, so that tapping on the whole Grid navigates to the url. How do I do access the URL property so that I can navigate to it?
<controls:Pivot VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Margin="0,0,0,0"
x:Name="PivotRoot"
Title="{Binding SmartTextStateModel.Title}"
SelectionChanged="Pivot_SelectionChanged"
Background="{StaticResource PhoneBackgroundBrush}">
<controls:PivotItem Header="{Binding Path=Labels.SmartTextBingHeaderLabel, Source={StaticResource Translations}}" Tag="bingsearch">
<ListBox ItemsSource="{Binding SmartTextStateModel.BingItemResults}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Tap="SmartTextElement_Tap">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="40" Text="{Binding Path=Title}" />
<TextBlock Grid.Row="1" TextWrapping="Wrap" FontSize="18.667" Foreground="{StaticResource PhoneDisabledBrush}"
TextTrimming="WordEllipsis" MaxHeight="100" Text="{Binding Path=Description}"/>
<TextBlock Grid.Row="2" Foreground="{StaticResource PhoneAccentBrush}" Text="{Binding Path=Url}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
...
</controls:Pivot>
and the class definition
public class SmartTextItemModel : BaseModel
{
private string _title;
private string _description;
private string _url;
/// <summary>
/// The title of the linked page (Large text)
/// </summary>
public string Title
{
get { return _title; }
set
{
if (_title != value)
{
_title = value;
NotifyPropertyChanged("Title");
}
}
}
/// <summary>
/// Description of the page (smaller text)
/// </summary>
public string Description
{
get { return _description; }
set
{
if (_description != value)
{
_description = value;
NotifyPropertyChanged("Description");
}
}
}
/// <summary>
/// Url of the page
/// </summary>
public string Url
{
get { return _url; }
set
{
if (_url != value)
{
_url = value;
NotifyPropertyChanged("Url");
}
}
}
public SmartTextItemModel(string _t, string _d, string _u)
{
this._title = _t;
this._description = _d;
this._url = _u;
}
}
Of course the event handler in the .cs file looks like this:
private void SmartTextElement_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
... ?
// Navigate to url...
}
Note: This was the closest StackOverflow question to mine: How to get the listbox item's properties after event "tap", but it still didn't help.
the Grid is inside the ItemTemplate of the ListBox. That means that the Grid.DataContext property is going to be an instance of your SmartTextItemModel class:
private void SmartTextElement_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var grid = sender as Grid;
if (grid == null)
return;
var item = grid.DataContext as SmartTextItemModel;
if (item == null)
return;
item.// Navigate to url...
}

Categories

Resources