講講我在Windows10(uwp)開發中遇到的一些坑
1.DataType在UWP中缺失的問題
在WPF中使用過MVVMLight的都知道,我們可以在App.xaml檔案中通過DataType將ViewModel和View繫結在一起.
<DataTemplate DataType="{x:Type vm:MyViewModel}">
<views:MyView/>
</DataTemplate>
但是在Windows10(包括WP7等),是沒有DataType的屬性的,這意味著我們不能用這種方式來實現ViewModel和View的繫結.但是我們可以曲線救國一下,通過key的方式來尋找DataTemplate來繫結.
首先,我們需要改變我們在UWP中的寫法.
<DataTemplate x:Key="MyViewModel"> <view:MyView/> </DataTemplate>
然後我們在我們的MainPage.xaml檔案中加入一個ContentControl.
<ContentControl Content="{Binding CurrentViewModel}" ContentTemplate="{Binding Path=CurrentTemplate}" />
我們的各個Views是用Usercontrol實現的.我們需要在MainPageViewModel中新增相應的繫結項.
public ViewModelBase CurrentViewModel { get { return currentViewModel; } set { if (currentViewModel == value) { return; } currentViewModel = value; RaisePropertyChanged(()=>CurrentViewModel); RaisePropertyChanged(()=>CurrentTemplate); } } public DataTemplate CurrentTemplate { get { if (CurrentViewModel == null) { return null; } return Untils.DataTemplateSelector.GetTemplate(CurrentViewModel); } }
DataTemplateSelector.GetTemplate是我們整個方法的核心.
public static class DataTemplateSelector
{
public static DataTemplate GetTemplate(ViewModelBase param)
{
Type t = param.GetType();
return App.Current.Resources[t.Name] as DataTemplate;
}
}
通過查詢Key的方式將ViewModel和View繫結在一起,這樣就實現了我們的功能.我們接下來只要關注App.xaml或者相關檔案中宣告我們的Key就行了.
WebView的Source屬性只能繫結微軟規定的一些地址協議,不能直接繫結HTML的內容.通過附加屬性可以解決這個問題,利用的是NavigateToString方法
public static readonly DependencyProperty SourceStringProperty =
DependencyProperty.RegisterAttached("SourceString", typeof(string), typeof(Untils), new PropertyMetadata("", OnSourceStringChanged));
public static string GetSourceString(DependencyObject obj) { return obj.GetValue(SourceStringProperty).ToString(); }
public static void SetSourceString(DependencyObject obj, string value) { obj.SetValue(SourceStringProperty, value); }
private static void OnSourceStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
WebView wv = d as WebView;
if (wv != null)
{
wv.NavigateToString(e.NewValue.ToString());
}
}
宣告一個SourceString的附加屬性,然後在變更事件中進行導航,然後Xaml檔案中:
<WebView Property:Untils.SourceString="{Binding Url,Mode=TwoWay}"/>
這樣子,就可以直接繫結Html內容了.
3.非同步(async)方法中的異常無法被App的UnhandledException捕獲的問題.
這是一個比較嚴重的問題.目前已知很多的做法就是區域性try catch來解決這個問題.這樣做是很容易導致Process被強制終止然後引起閃退的問題的.
我這裡用了一個執行緒同步模型類解決這個問題.
using System;
using System.Threading;
using Windows.UI.Xaml.Controls;
namespace AiJianShu.ExceptionHandler
{
internal class ExceptionHandlingSynchronizationContext : SynchronizationContext
{
/// <summary>
/// 註冊事件. 需要在OnLaunched和OnActivated事件中呼叫
/// </summary>
/// <returns></returns>
public static ExceptionHandlingSynchronizationContext Register()
{
var syncContext = Current;
if (syncContext == null)
throw new InvalidOperationException("Ensure a synchronization context exists before calling this method.");
var customSynchronizationContext = syncContext as ExceptionHandlingSynchronizationContext;
if (customSynchronizationContext == null)
{
customSynchronizationContext = new ExceptionHandlingSynchronizationContext(syncContext);
SetSynchronizationContext(customSynchronizationContext);
}
return customSynchronizationContext;
}
/// <summary>
/// 將執行緒的上下文繫結到特定的Frame上面
/// </summary>
/// <param name="rootFrame"></param>
/// <returns></returns>
public static ExceptionHandlingSynchronizationContext RegisterForFrame(Frame rootFrame)
{
if (rootFrame == null)
throw new ArgumentNullException("rootFrame");
var synchronizationContext = Register();
rootFrame.Navigating += (sender, args) => EnsureContext(synchronizationContext);
rootFrame.Loaded += (sender, args) => EnsureContext(synchronizationContext);
return synchronizationContext;
}
private static void EnsureContext(SynchronizationContext context)
{
if (Current != context)
SetSynchronizationContext(context);
}
private readonly SynchronizationContext _syncContext;
public ExceptionHandlingSynchronizationContext(SynchronizationContext syncContext)
{
_syncContext = syncContext;
}
public override SynchronizationContext CreateCopy()
{
return new ExceptionHandlingSynchronizationContext(_syncContext.CreateCopy());
}
public override void OperationCompleted()
{
_syncContext.OperationCompleted();
}
public override void OperationStarted()
{
_syncContext.OperationStarted();
}
public override void Post(SendOrPostCallback d, object state)
{
_syncContext.Post(WrapCallback(d), state);
}
public override void Send(SendOrPostCallback d, object state)
{
_syncContext.Send(d, state);
}
private SendOrPostCallback WrapCallback(SendOrPostCallback sendOrPostCallback)
{
return state =>
{
try
{
sendOrPostCallback(state);
}
catch (Exception ex)
{
if (!HandleException(ex))
throw;
}
};
}
private bool HandleException(Exception exception)
{
if (UnhandledException == null)
return false;
var exWrapper = new AysncUnhandledExceptionEventArgs
{
Exception = exception
};
UnhandledException(this, exWrapper);
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
if (System.Diagnostics.Debugger.IsAttached) System.Diagnostics.Debugger.Break();
#endif
return exWrapper.Handled;
}
public event EventHandler<AysncUnhandledExceptionEventArgs> UnhandledException;
}
public class AysncUnhandledExceptionEventArgs : EventArgs
{
public bool Handled { get; set; }
public Exception Exception { get; set; }
}
}
使用例項:
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
this.UnhandledException += App_UnhandledException;
}
private void RegisterExceptionHandlingSynchronizationContext()
{
ExceptionHandlingSynchronizationContext
.Register()
.UnhandledException += SynchronizationContext_UnhandledException;
}
private async void App_UnhandledException(object sender, Windows.UI.Xaml.UnhandledExceptionEventArgs e)
{
e.Handled = true;
await new MessageDialog("Application Unhandled Exception:\r\n" + e.Exception.Message)
.ShowAsync();
}
private async void SynchronizationContext_UnhandledException(object sender, AysncUnhandledExceptionEventArgs e)
{
e.Handled = true;
await new MessageDialog("Synchronization Context Unhandled Exception:\r\n" + e.Exception.Message)
.ShowAsync();
}
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
RegisterExceptionHandlingSynchronizationContext();
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
this.DebugSettings.EnableFrameRateCounter = true;
}
#endif
Frame rootFrame = Window.Current.Content as Frame;
// 不要在視窗已包含內容時重複應用程式初始化,
// 只需確保視窗處於活動狀態
if (rootFrame == null)
{
// 建立要充當導航上下文的框架,並導航到第一頁
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: 從之前掛起的應用程式載入狀態
}
// 將框架放在當前視窗中
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
// 當導航堆疊尚未還原時,導航到第一頁,
// 並通過將所需資訊作為導航引數傳入來配置
// 引數
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
// 確保當前視窗處於活動狀態
Window.Current.Activate();
}
protected override void OnActivated(IActivatedEventArgs args)
{
RegisterExceptionHandlingSynchronizationContext();
base.OnActivated(args);
}
這樣全域性的異常就都能在App.xaml.cs檔案中被捕獲,不會導致閃退.
來自開發者交流群:53078485,期待您的加入!
相關推薦
講講我在Windows10(uwp)開發中遇到的一些坑
7月29日釋出的Windows10正式版,當天安裝好以後,在網路不太好的情況下,經過多次嘗試終於裝上了Visual Studio 2015和Windows 10 10240的SDK.這兩週一直在開發UWP,講講在其中遇到的一些坑,不定時更新,有興趣的可以關注下. 1.Dat
最近開發中的一些坑#1
牢騷 最近回學校, 聽說阿里好多實習生都被拒了, 不過大概都被撿漏了, UC這方面還沒動靜, 不知道是打算把我當臨時工使還是怎麼, 有點煩躁, 還是得加強自己的能力才行. 最近半年一直在做音樂播放器專案, 開發期間遇到了許多奇怪的問題, 有些我單獨寫了文章,
JS開發中的一些小技巧和方法
hello floor apply subst shuf 新的 情況 level 可能 生成指定範圍內的隨機數 當我們需要獲取指定範圍(min,max)內的整數的時候,下面的代碼非常適合;這段代碼用的還挺多的。 function setRadomNum(min,m
onvif 開發中的一些重要函數介紹
目的 uri www. ror art interface tags -c end ?soap結構中count(soap->count)成員 soap結構中count(soap->count)成員記錄的是http協議中Content-Length的數值。?
PEP8編碼規範,及開發中的一些慣例和建議
ret mar 小寫 比較運算 -c 包含 user def 有意 為什麽要有編碼規範 規範的代碼給人的第一感覺是【美觀】,美的東西總是更加的吸引人,也願意觀看。亂糟糟得是不是會讓人不由自主地想飆臟話。所以美觀進而帶來的是代碼的【可讀性】強,想一想你寫的代碼可讀性非常高
PEP8 編碼規範, 及開發中的?一些慣例例和建議
urn 命名 體積 size family 數學運算 lint 字母 style 首先看下面這段代碼,是否滿足編碼規範 1 from django.conf import settings 2 from user.models import * 3 imp
【UE4實用技能】UE4藍圖開發中的一些小細節
加載圖標 com ges 路徑 icons 就是 技能 9.png tab 1.加載圖標Icon路徑:/Game/Arts/UI/TableIcons/Task_Icon/Achievement/Task_icon_weixin.Task_icon_weixin(就是Con
Dubbo在開發中的一些常用配置
如果 本地 code info 技術 不兼容 mil 是否可用 文檔 介紹Dubbo在開發中的一些常用配置,文中內容主要參考dubbo文檔配置和示例兩節,詳細可移步訪問 傳送站 1. 屬性配置方法及加載順序 屬性常用配置方法主要有三種: 第一種是通過啟動時在虛擬
React-Native開發十 react-navigation開發中的一些常見的坑
1 前言 都說RN開發效率高,一次學習隨處編寫。真的用RN開發了一個APP才知道,RN中坑真是太多,特別是很多坑只有在生產模式下才會出現,在平常的debug模式下,APP執行好好的,但是你一旦打正式包,就會發現各種報錯,各種崩潰,如果在Android平臺下,各種相容性,各種奇葩的問題
以前開發中的一些記錄
ApplicationThread && H ActivityThread ActivityThread 應用程式的入口 ViewRootImpl---->負責View的測量繪製 DectorView --->PhoneWindow的內部類,是一個應用程式程式
js 開發中的一些小技巧
js 取到的值*1就會自動轉化為數字型別 js 中的三目運算 {{d.amount?a.amount:""}} ==> 只要d.amount有值就是true JS防止複製&nbs
Java架構-Java開發中的一些小技巧
一、 Java獲取URL地址中傳遞的引數 二、獲取請求的URL地址 三、獲取請求的IP地址 四:判斷字串是否能夠轉換成指定格式的日期 希望此文能幫到大家的同時,也聽聽大家的觀點。歡迎留言討論,加關注,分享你的高見!持續更新! 我本人邀約各大BATJ
嵌入式開發中的一些硬體設計上的坑
做嵌入式系統開發,經常要接觸硬體。做嵌入式開發對數位電路和類比電路要有一定的瞭解。這樣才能深入的研究下去。下面我們簡單的介紹嵌入式開發中的一些硬體相關的概念。 電平(Level) 在數位電路中,分為高電平和低電平,分別用1和0表示。一個數字電路的管腳,總是存在一
Java開發中的一些常用手段
用 BeanUtils應注意的事項: 引用: import org.springframework.beans.BeanUtils; 參考格式: BeanUtils.copyProperties(productInfo, orderDetail);//記住先拷貝 後賦
敏捷開發中個一些概念及要點
名詞一:backlog 一、什麼是迭代backlog 1、迭代Backlog是團隊在一輪迭代中需要完成的 任務清單,是迭代計劃會議確定的內容; 2、迭代Backlog是團隊在召開迭代計劃會議的時 候從產品Backlog挑選出高優先順序的需求清單; 3、每項任務資訊包含當前剩
敏捷開發中的一些教訓和感悟
工作一年多了,所在的公司採用敏捷開發。作為小團隊裡一名普通的開發者, 既體會到了敏捷的優點,也收穫了很多經驗教訓。在此記錄一下自己地感悟,如果有朝一日自己去領導一個敏捷開發團隊,要儘量想辦法避免和解決這些問題。 背景介紹: 公司的開發進度是大概每5-7周釋出一個小版本,這裡
realsense2在開發中的一些方法(深度幀與其對應的顏色幀對齊示例)
#rs-align Sample ##概述 此示例演示了`rs2 :: align`物件的用法,該物件允許使用者在深度和其他一些流(投影方式)之間進行對齊,反之亦然。點選 對齊實用程式基於所提供的深度資料執行每畫素幾何變換,並且不適合於對齊本質上為2D的影象,例如顏色,IR或魚眼。此外,轉換需要進行
java開發中的一些經驗
2018-12-28 1.雙邊閉區間; 在javaweb開發中,儘量不要使用單邊封閉條件查詢。例如:date》‘2018-12-12’。最好使用雙邊封閉查詢,哪怕另一邊設定一個較大的數值也好。例如:date>‘20
Springboot開發中的一些小坑——CSS失效問題
Springboot版本1.5.17 結合thymeleaf,在專案中引用CSS檔案的問題 <parent> <groupId>org.springframework.boot</groupId> <
關於專案開發中的一些問題
1 軟體工程就意味著無休止的會議嗎?怎麼樣才能更好的將任務佈置給每一個人,保證進度,並且在其遇到難題的時候能夠更好的溝通呢? 2 在開發中間[我說的是WEB開發],頁面顯示的修改在總的工作量上所站的比例是多少呢? 3 程式程式碼的註釋要詳細到什麼程度呢