[Open-source, learning, sharing] UWP third-party simplified book client sharing, uwp simplified book
Introduction
Since the official version of Windows 10 was released, I have used some time to learn about UWP and developed a third-party simplified book App based on this technology.
Basic Interface
Youku video:
Http://v.youku.com/v_show/id_XMTM2MjU4MjI4NA==.html
Basic functions
- The client uses UWP technology, so it supports x86, x64, and ARM platforms. It adopts a responsive layout and partially optimizes the mobile phone.
- SQLite and local storage are encapsulated to support caching.
The cache supports synchronous and asynchronous methods, and implements two interfaces respectively:
internal interface IStorage{ void AddItem(string key, object value); void UpdateItem(string key, object value); bool ContainItem(string key); void FlushAll(); T GetItem<T>(string key) where T : class; List<T> GetItems<T>(string key) where T : class; bool RemoveItem(string key); long GetSize();}interface IStorageAsync{ Task AddItemAsync(string key, object value); Task UpdateItemAsync(string key, object value); Task<bool> ContainItemAsync(string key); Task FlushAllAsync(); Task<T> GetItemAsync<T>(string key) where T : class; Task<List<T>> GetItemsAsync<T>(string key) where T : class; Task<bool> RemoveItemAsync(string key); long GetSize();}The Key and Value methods are used to increase, decrease, and delete.
- It simply encapsulates Sina Weibo's Image Sharing and text functions. You can add your own key and secret to the Config. cs file.
public async Task<WeiboResult> ShareTextAsync(string text){ if (text == null) { throw new ArgumentNullException(nameof(text)); } if (string.IsNullOrWhiteSpace(text)) { throw new ArgumentException("Text could not be empty", nameof(text)); } if (!UserInfo.CheckUseable()) { string authorizeCode = await this.GetAuthorizeCodeAsync(); await this.Authorize(authorizeCode); } Uri uri = new Uri("https://api.weibo.com/2/statuses/update.json"); Dictionary<string, string> pairs = new Dictionary<string, string>(); pairs.Add("access_token", UserInfo.Token); pairs.Add("status", text); HttpFormUrlEncodedContent content = new HttpFormUrlEncodedContent(pairs); using (HttpClient client = new HttpClient()) { HttpResponseMessage response; try { response = await client.PostAsync(uri, content); } catch (Exception ex) { throw new Exception("Network error", ex); } return await response.Content.ReadAsJsonAsync<WeiboResult>(); }}public async Task<WeiboResult> ShareImageAsync(byte[] image, string text){ if (image == null) { throw new ArgumentNullException(nameof(image)); } if (text == null) { throw new ArgumentNullException(nameof(text)); } if (string.IsNullOrWhiteSpace(text)) { throw new ArgumentException("Text could not be empty", nameof(text)); } if (!UserInfo.CheckUseable()) { string authorizeCode = await this.GetAuthorizeCodeAsync(); await this.Authorize(authorizeCode); } Uri uri = new Uri("https://upload.api.weibo.com/2/statuses/upload.json"); HttpBufferContent bufferContent = new HttpBufferContent(image.AsBuffer()); HttpMultipartFormDataContent content = new HttpMultipartFormDataContent(); content.Add(new HttpStringContent(UserInfo.Token), "access_token"); content.Add(new HttpStringContent(text), "status"); content.Add(bufferContent, "pic", "pic.jpg"); using (HttpClient client = new HttpClient()) { HttpResponseMessage response; try { response = await client.PostAsync(uri, content); } catch (Exception ex) { throw new Exception("Network error", ex); } return await response.Content.ReadAsJsonAsync<WeiboResult>(); }}
- Added support for asynchronous thread error handling and asynchronous Command.
Asynchronous thread processing I have mentioned in my previous article "talking about some pitfalls I encountered in Windows 10 (uwp) Development". Here I will post the asynchronous Command code:
public class AsyncCommand : AsyncCommandBase{ private readonly Func<Task> command; public AsyncCommand(Func<Task> command) { this.command = command; } public override bool CanExecute(object parameter) { return true; } public override Task ExecuteAsync(object parameter) { return command(); }}
- Supports pull-down refresh and loading more (but there are bugs ).
For the UWP pull-down refresh, I have seen several implementation methods in the blog:
UWP pull-down refresh implementation
Only one method is pasted, because currently the pull-down refresh method is implemented by setting a ScrollViewer outside the ListView. A serious problem is that there is a ScrollViewer inside the ListView, when sliding, The ScrollViewer inside the ListView is compressed, which directly causes the failure of pulling down and refreshing.
Here I think about another way, that is, to operate the ScrollViewer inside the ListView.
<ScrollViewer Margin="0,0,0,-100" RenderTransformOrigin="0.5,0.5" x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" TabNavigation="{TemplateBinding TabNavigation}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}"> <ScrollViewer.RenderTransform> <CompositeTransform TranslateY="-100" /> </ScrollViewer.RenderTransform> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Border Height="{TemplateBinding RefreshHeaderHeight}" x:Name="PullToRefreshIndicator" Background="Transparent"> <Grid HorizontalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto" /> <ColumnDefinition Width="auto" /> </Grid.ColumnDefinitions> <Grid Width="40"> <Viewbox x:Name="Arrow" Height="15" VerticalAlignment="Top" Margin="0,4,0,0" RenderTransformOrigin="0.5,0.5"> <Viewbox.RenderTransform> <CompositeTransform Rotation="180" /> </Viewbox.RenderTransform> <Image Source="ms-appx:///Assets/arrow.png" Width="12" Height="12.9999"/> <!--<Path Width="12" Height="12.9999" Stretch="Fill" Fill="{TemplateBinding ArrowColor}" Data="M 20.4289,10.4376L 25,15.0087L 23.571,16.4376L 20.0291,12.8957L 20.0291,21.9999L 18.0083,21.9999L 18.0083,12.8583L 14.4289,16.4377L 13,15.0087L 17.5624,10.429L 19.0087,9" />--> </Viewbox> </Grid> <TextBlock Grid.Column="1" x:Name="PullPart" Text="{TemplateBinding PullPartTemplate}"/> <TextBlock Grid.Column="1" Visibility="Collapsed" x:Name="ReleasePart" Text="{TemplateBinding ReleasePartTemplate}"/> </Grid> </Border> <ItemsPresenter FooterTransitions="{TemplateBinding FooterTransitions}" FooterTemplate="{TemplateBinding FooterTemplate}" Footer="{TemplateBinding Footer}" HeaderTemplate="{TemplateBinding HeaderTemplate}" Header="{TemplateBinding Header}" HeaderTransitions="{TemplateBinding HeaderTransitions}" Padding="{TemplateBinding Padding}" Grid.Row="1"/> </Grid></ScrollViewer>Compress the internal ScrollViewer so that you can get the user's pull-down more accurately.
At the same time, I have encapsulated this code into a separate control. You can obtain the source code from the following link:
Https://github.com/youngytj/uwp_PullToRefreshListview
To use this function, you only need to add the following code in xaml:
<local:PullToRefreshListView x:Name="lv" PullPartTemplate="Pull" ReleasePartTemplate="Release" RefreshContent="lv_RefreshContent" MoreContent="lv_MoreContent"/>
PullPartTemplate and ReleasePartTemplate are the text in the drop-down and release respectively, and then the events are updated and loaded in more cases.
- MVVMLight is used, and all interfaces are embedded in MainPage.
Content in MainPage is bound through ContentControl
<ContentControl Content="{Binding CurrentViewModel}" ContentTemplate="{Binding Path=CurrentTemplate}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/>The binding of View and ViewModel is placed in App. xaml.
<Application.Resources> <ResourceDictionary> <vm:ViewModelLocator x:Key="Locator"/> <DataTemplate x:Key="HomeViewModel"> <view:HomeView/> </DataTemplate> ...</Application.Resources>
Note that View only exists as a resource. When page conversion occurs in MainPage, The ViewModel name is used as a Key (so the class name must be a Key) to find the View.
public static class DataTemplateSelector{ public static DataTemplate GetTemplate(ViewModelBase param) { Type t = param.GetType(); if(!views.ContainsKey(t.Name)) { views.Add(t.Name, App.Current.Resources[t.Name] as DataTemplate); } return views[t.Name]; }}
Open Source Address
I have not uploaded the package to the market because I cannot upload the package on the network. If the network environment is ready, I will consider uploading the package. The following is the Github Source Code address:
Github
Conclusion
I am not very optimistic about Microsoft's cross-platform implementation. in addition to the immature UWP technology, there are many shortcomings, such as asynchronous thread processing problems, lack of support for mobile sliding (unlike android, you can start to implement a mobile-like gesture operation from the underlying layer, and the problem still exists in ScrollViewer .), there is also a cross-platform approach like Microsoft, which I support-the biggest obstacle for cross-platform platforms is the difference in user experience caused by different hardware devices and operating environments! This obstacle cannot be solved by any "technology" or "technology provider !. In general, because it is a brand new platform with few open-source components, it takes some time to get familiar with the platform. The platform also has its own shortcomings.
This client has many disadvantages, such as insufficient control over asynchronous thread startup and shutdown, lack of logs, lack of cache system management, and lack of navigation systems, client Optimization in different network environments. but I think it is enough to be a research project. if you like or support such a project, click here for a recommendation.
Now, thank you.