Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a cikk bemutatja, hogyan hozhat létre egy egyszerű widget-szolgáltatót, amely megvalósítja az IWidgetProvider felületet. Ennek a felületnek a metódusait a widget-gazdagép meghívja, hogy kérje le a widgetet meghatározó adatokat, vagy hogy a widgetszolgáltató válaszoljon egy widget felhasználói műveletére. A widgetszolgáltatók egyetlen vagy több widgetet is támogathatnak. Ebben a példában két különböző widgetet határozunk meg. Az egyik widget egy szimulált időjárási widget, amely bemutatja a Adaptív kártyák keretrendszer által biztosított formázási lehetőségek némelyikét. A második widget bemutatja a felhasználói műveleteket és az egyéni widgetállapot-funkciót egy olyan számláló fenntartásával, amely növekszik, amikor a felhasználó a widgeten megjelenő gombra kattint.
A cikkben szereplő mintakód a Windows App SDK widgetek mintájából származik. A widget-szolgáltató C++/WinRT használatával történő implementálásához lásd: Widget-szolgáltató implementálása win32-alkalmazásban (C++/WinRT).
Előfeltételek
- Teszteléshez elérhető Widgets Boarddal rendelkező Windows 11-eszköz.
- Az eszköznek engedélyeznie kell a fejlesztői módot. További információ: Beállítások fejlesztőknek.
- Visual Studio 2022 vagy újabb verzió a WinUI-alkalmazásfejlesztési számítási feladattal.
Új C#-konzolalkalmazás létrehozása
Visual Studio-ban hozzon létre egy új projektet. A Új projekt létrehozása párbeszédpanelen állítsa a nyelvi szűrőt "C#" értékre, a platformszűrőt pedig Windows, majd válassza ki a Konzolalkalmazás projektsablont. Nevezze el az új projektet "ExampleWidgetProvider" néven. Amikor a rendszer kéri, állítsa a cél .NET verziót 8.0-ra.
Amikor a projekt betöltődik, a Megoldáskezelő kattintson a jobb gombbal a projekt nevére, és válassza a Properties lehetőséget. A General lapon görgessen le a Target OS lapra, és válassza a "Windows" lehetőséget. A Cél operációsrendszer-verzió területen válassza a 10.0.19041.0-s vagy újabb verziót.
Ha frissíteni szeretné a project a 8.0-s .NET támogatásához, a Megoldáskezelő kattintson a jobb gombbal a project nevére, és válassza a Szerkesztés Project Fájl lehetőséget. A Tulajdonságcsoporton belül adja hozzá a következő RuntimeIdentifiers elemet.
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
Vegye figyelembe, hogy ez az útmutató egy konzolalkalmazást használ, amely megjeleníti a konzolablakot a widget aktiválásakor a könnyű hibakeresés érdekében. Ha készen áll a widget szolgáltatóalkalmazás közzétételére, a konzolalkalmazást Windows alkalmazássá alakíthatja át a Konvertálja a konzolalkalmazást Windows alkalmazássá útmutatót követve.
Hivatkozások hozzáadása a Windows App SDK-hoz
Ez az útmutató a Microsoft.WindowsAppSDK 2.5.1-et használja. A Megoldáskezelő kattintson a jobb gombbal a Dependencies elemre, és válassza a Manage NuGet-csomagok... . A NuGet-csomagkezelőben válassza a Browse lapot, és keresse meg a "Microsoft. WindowsAppSDK". Válassza ki a 2.5.1-es vagy újabb támogatott stabil verziót a Windows App SDK kiadási csatornái közül, majd kattintson a Telepítés gombra. Használja ugyanazt a csomagverziót az alkalmazásban és a csomagkészítési projektekben. Ez az útmutató által használt verzió, nem pedig a widget API-kat bevezetett minimális verzió.
WidgetProvider-osztály hozzáadása a widgetműveletek kezeléséhez
A Visual Studio kattintson a jobb gombbal a ExampleWidgetProvider projektre Megoldáskezelő, majd válassza a Add->Class lehetőséget. Az Osztály hozzáadása párbeszédpanelen nevezze el a "WidgetProvider" osztályt, majd kattintson a hozzáadása elemre. A létrehozott WidgetProvider.cs fájlban frissítse az osztálydefiníciót, hogy azt jelezze, hogy implementálja az IWidgetProvider felületet.
// WidgetProvider.cs
internal class WidgetProvider : IWidgetProvider
Felkészülés az engedélyezett widgetek nyomon követésére
A widget-szolgáltatók egyetlen vagy több widgetet is támogathatnak. Amikor a widget-gazdagép műveletet kezdeményez a widget-szolgáltatónál, egy azonosítót ad át a művelethez társított widget azonosításához. Minden vezérlőhöz tartozik egy társított név és egy állapotérték is, amely egyéni adatok tárolására használható. Ebben a példában egy egyszerű segédstruktúrát deklarálunk az egyes rögzített vezérlők azonosítójának, nevének és adatainak tárolásához. A widgetek aktív állapotban is lehetnek, amelyet az alábbi Aktiválás és inaktiválás szakaszban ismertetünk, és ezt az állapotot minden widget esetében logikai értékkel követjük nyomon. Adja hozzá a következő definíciót a WidgetProvider.cs fájlhoz az ExampleWidgetProvider névtérben, de a WidgetProvider osztálydefiníción kívül.
// WidgetProvider.cs
public class CompactWidgetInfo
{
public string? widgetId { get; set; }
public string? widgetName { get; set; }
public int customState = 0;
public bool isActive = false;
}
A WidgetProvider.cs WidgetProvider osztálydefiníciójában adjon hozzá egy tagot a térképhez, amely megőrzi az engedélyezett widgetek listáját, és minden bejegyzéshez kulcsként használja a widget azonosítóját.
// WidgetProvider.cs
// Class member of WidgetProvider
public static Dictionary<string, CompactWidgetInfo> RunningWidgets = new Dictionary<string, CompactWidgetInfo>();
Widgetsablon JSON-sztringjeinek deklarálása
Ez a példa néhány statikus sztringet deklarál az egyes vezérlők JSON-sablonjainak meghatározásához. A kényelem érdekében ezek a sablonok a WidgetProvider osztály tagváltozóiban vannak tárolva. Ha általános tárterületre van szüksége a sablonokhoz , az alkalmazáscsomag részeként is felvehetők: Csomagfájlok elérése. A widgetsablon JSON-dokumentumának létrehozásáról a Widgetsablon létrehozása a Adaptív kártyák Tervezővel című témakörben olvashat.
A Windows widgeteket implementáló alkalmazások testre szabhatják a widgethez megjelenített fejlécet olyan gazdagépeken, amelyek támogatják a fejléc testreszabását. További információ: A widget fejlécterületének testreszabása.
Megjegyzés:
Egy webes widget URL-címből kiszolgált HTML-t jeleníthet meg. A szolgáltató továbbra is egy Adaptive Card JSON-adatcsomagot biztosít az URL-cím megadásához, és továbbra is implementálja az IWidgetProvider. Az erőforrás- és üzenetkezelési API-k az Windows App SDK 1.6.3-ban lettek bevezetve. A beállítási és gazdagép-követelményekről a Web widget szolgáltatók című cikkben olvashat.
// WidgetProvider.cs
// Class members of WidgetProvider
const string weatherWidgetTemplate = """
{
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.0",
"speak": "<s>The forecast for Seattle January 20 is mostly clear with a High of 51 degrees and Low of 40 degrees</s>",
"backgroundImage": "https://raw.githubusercontent.com/microsoft/AdaptiveCards/59402c8d43f7a69a68e0b4fccc08f8a76fc98ccd/source/nodejs/adaptivecards-site/themes/adaptivecards/source/content/Mostly%20Cloudy-Background.jpg",
"body": [
{
"type": "TextBlock",
"text": "Redmond, WA",
"size": "large",
"isSubtle": true,
"wrap": true
},
{
"type": "TextBlock",
"text": "Mon, Nov 4, 2019 6:21 PM",
"spacing": "none",
"wrap": true
},
{
"type": "ColumnSet",
"columns": [
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "Image",
"url": "https://raw.githubusercontent.com/microsoft/AdaptiveCards/59402c8d43f7a69a68e0b4fccc08f8a76fc98ccd/source/nodejs/adaptivecards-site/themes/adaptivecards/source/content/Mostly%20Cloudy-Square.png",
"size": "small",
"altText": "Mostly cloudy weather"
}
]
},
{
"type": "Column",
"width": "auto",
"items": [
{
"type": "TextBlock",
"text": "46",
"size": "extraLarge",
"spacing": "none",
"wrap": true
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "°F",
"weight": "bolder",
"spacing": "small",
"wrap": true
}
]
},
{
"type": "Column",
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "Hi 50",
"horizontalAlignment": "left",
"wrap": true
},
{
"type": "TextBlock",
"text": "Lo 41",
"horizontalAlignment": "left",
"spacing": "none",
"wrap": true
}
]
}
]
}
]
}
""";
const string countWidgetTemplate = """
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "You have clicked the button ${count} times"
},
{
"text":"Rendering Only if Small",
"type":"TextBlock",
"$when":"${$host.widgetSize==\"small\"}"
},
{
"text":"Rendering Only if Medium",
"type":"TextBlock",
"$when":"${$host.widgetSize==\"medium\"}"
},
{
"text":"Rendering Only if Large",
"type":"TextBlock",
"$when":"${$host.widgetSize==\"large\"}"
}
],
"actions": [
{
"type": "Action.Execute",
"title": "Increment",
"verb": "inc"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.5"
}
""";
Az IWidgetProvider metódusok implementálása
A következő néhány szakaszban implementáljuk az IWidgetProvider felület módszereit. A cikk későbbi részében megjelenik az a UpdateWidget segítő metódus, amelyet több ilyen metódusmegvalósításban is meghívnak.
Megjegyzés:
Az IWidgetProvider felület visszahívási metódusaiba átadott objektumok csak a visszahíváson belül lesznek érvényesek. Ne tároljon hivatkozásokat ezekre az objektumokra, mert a visszahívás környezetén kívüli viselkedésük nincs meghatározva.
CreateWidget
A widget-gazdagép meghívja a CreateWidgetet , amikor a felhasználó az alkalmazás egyik widgetjét rögzítette a widget-gazdagépen. Először is ez a módszer lekéri a társított widget azonosítóját és nevét, és hozzáad egy új példányt a compactWidgetInfo segédstruktúránkhoz az engedélyezett widgetek gyűjteményéhez. Ezután elküldjük a widget kezdeti sablonját és adatait, amely az UpdateWidget segédmetódusban van beágyazva.
// WidgetProvider.cs
public void CreateWidget(WidgetContext widgetContext)
{
var widgetId = widgetContext.Id; // To save RPC calls
var widgetName = widgetContext.DefinitionId;
CompactWidgetInfo runningWidgetInfo = new CompactWidgetInfo() { widgetId = widgetId, widgetName = widgetName };
RunningWidgets[widgetId] = runningWidgetInfo;
// Update the widget
UpdateWidget(runningWidgetInfo);
}
Widget törlése
A widget-gazdagép akkor hívja meg a DeleteWidgetet , ha a felhasználó törölte az alkalmazás egyik widgetét a widget-gazdagépről. Ha ez történik, eltávolítjuk a társított widgetet az engedélyezett widgetek listájából, hogy ne küldhessünk további frissítéseket a widgethez.
// WidgetProvider.cs
public void DeleteWidget(string widgetId, string customState)
{
RunningWidgets.Remove(widgetId);
if(RunningWidgets.Count == 0)
{
emptyWidgetListEvent.Set();
}
}
Ebben a példában amellett, hogy eltávolítjuk a widgetet az engedélyezett widgetek listájából, azt is ellenőrizzük, hogy a lista üres-e, és ha igen, akkor beállítunk egy eseményt, amely később lesz használva, hogy az alkalmazás kiléphessen, ha nincsenek engedélyezett widgetek. Az osztálydefiníción belül adja hozzá a ManualResetEvent deklarációját és egy nyilvános kiegészítő függvényt.
// WidgetProvider.cs
static ManualResetEvent emptyWidgetListEvent = new ManualResetEvent(false);
public static ManualResetEvent GetEmptyWidgetListEvent()
{
return emptyWidgetListEvent;
}
OnActionInvoked
A widget-gazdagép meghívja az OnActionInvoked parancsot , amikor a felhasználó egy, a widgetsablonban meghatározott művelettel lép kapcsolatba. Az ebben a példában használt számláló widget esetében a widget JSON-sablonjában egy "inc" értékű műveletet deklaráltak. A widget-szolgáltató kódja ezt az igeértéket használja annak meghatározására, hogy milyen műveletet kell elvégezni a felhasználói beavatkozásra válaszul.
...
"actions": [
{
"type": "Action.Execute",
"title": "Increment",
"verb": "inc"
}
],
...
Az OnActionInvoked metódusban szerezze meg az ige értékét a WidgetActionInvokedArgs objektum Verb tulajdonságának ellenőrzésével. Ha az ige "inc", akkor tudjuk, hogy a widget testreszabott állapotában növelni fogjuk a számlálót. A WidgetActionInvokedArgs objektumból kérje le a WidgetContext objektumot, majd annak Id tulajdonságát a frissített widgetpéldány azonosításához. Keresse meg a bejegyzést az engedélyezett widgetek térképén a megadott azonosítóval, majd frissítse a növekmények tárolásához használt egyéni állapotértéket. Végül frissítse a widget tartalmát az új értékkel az UpdateWidget segédfüggvénnyel.
// WidgetProvider.cs
public void OnActionInvoked(WidgetActionInvokedArgs actionInvokedArgs)
{
var verb = actionInvokedArgs.Verb;
if (verb == "inc")
{
var widgetId = actionInvokedArgs.WidgetContext.Id;
// If you need to use some data that was passed in after
// Action was invoked, you can get it from the args:
var data = actionInvokedArgs.Data;
if (RunningWidgets.ContainsKey(widgetId))
{
var localWidgetInfo = RunningWidgets[widgetId];
// Increment the count
localWidgetInfo.customState++;
UpdateWidget(localWidgetInfo);
}
}
}
Az Adaptív kártyák Action.Execute szintaxisáról lásd: Action.Execute. A widgetek interakciójának tervezésével kapcsolatos útmutatásért tekintse meg a widgetek interakciójának tervezési útmutatóját.
OnWidgetContextChanged
Az aktuális kiadásban az OnWidgetContextChanged csak akkor lesz meghívva, ha a felhasználó módosítja a rögzített widget méretét. A kért mérettől függően másik JSON-sablont/adatot adhat vissza a widget-gazdagépnek. A JSON sablont úgy is megtervezheti, hogy a host.widgetSize értékétől függően feltételes rendereléssel támogassa az összes elérhető méretet. Ha nem kell új sablont vagy adatokat küldenie a méretváltozáshoz, az OnWidgetContextChanged telemetriai célokra használható.
// WidgetProvider.cs
public void OnWidgetContextChanged(WidgetContextChangedArgs contextChangedArgs)
{
var widgetContext = contextChangedArgs.WidgetContext;
var widgetId = widgetContext.Id;
var widgetSize = widgetContext.Size;
if (RunningWidgets.ContainsKey(widgetId))
{
var localWidgetInfo = RunningWidgets[widgetId];
UpdateWidget(localWidgetInfo);
}
}
Aktiválás és inaktiválás
Az Activate metódust meghívva értesítheti a widget-szolgáltatót arról, hogy a widget-gazdagép jelenleg szeretne frissített tartalmat kapni a szolgáltatótól. Ez például azt jelentheti, hogy a felhasználó jelenleg aktívan tekinti meg a widget-gazdagépet. A rendszer meghívja az Inaktiválás metódust, amely értesíti a widget-szolgáltatót arról, hogy a widget-gazdagép már nem kér tartalomfrissítéseket. Ez a két módszer határoz meg egy ablakot, amelyben a widget-gazdagép leginkább a up-to-date tartalmat szeretné ábrázolni. A widget-szolgáltatók bármikor küldhetnek frissítéseket a widgetnek, például leküldéses értesítésre reagálva, de mint minden háttérfeladat esetén, fontos, hogy a naprakész tartalom biztosítása egyensúlyban legyen az erőforrásokkal kapcsolatos aggályokkal, például az akkumulátor élettartamával.
aktiválása és Inaktiválás meghívása widgetenként történik. Ez a példa a CompactWidgetInfo segédstruktúra egyes vezérlőinek aktív állapotát követi nyomon. Az Aktiválás metódusban meghívjuk az UpdateWidget segédmetódust a widget frissítéséhez. Vegye figyelembe, hogy az aktiválás és az inaktiválás közötti időablak kicsi lehet, ezért javasoljuk, hogy próbálja meg a lehető leggyorsabban frissíteni a widget kódját.
// WidgetProvider.cs
public void Activate(WidgetContext widgetContext)
{
var widgetId = widgetContext.Id;
if (RunningWidgets.ContainsKey(widgetId))
{
var localWidgetInfo = RunningWidgets[widgetId];
localWidgetInfo.isActive = true;
UpdateWidget(localWidgetInfo);
}
}
public void Deactivate(string widgetId)
{
if (RunningWidgets.ContainsKey(widgetId))
{
var localWidgetInfo = RunningWidgets[widgetId];
localWidgetInfo.isActive = false;
}
}
Widget frissítése
Adja meg az UpdateWidget segédmetódusát egy engedélyezett widget frissítéséhez. Ebben a példában ellenőrizzük a CompactWidgetInfo segédstruktúrában átadott widget nevét, majd beállítjuk a megfelelő sablont és annak adat JSON-ját, annak függvényében, hogy melyik widgetet frissítjük. A WidgetUpdateRequestOptions inicializálva van a frissített widget sablonjával, adataival és egyéni állapotával. Hívja meg a WidgetManager::GetDefault parancsot a WidgetManager osztály egy példányának lekéréséhez, majd az UpdateWidget hívásával küldje el a frissített widgetadatokat a widget-gazdagépnek.
// WidgetProvider.cs
void UpdateWidget(CompactWidgetInfo localWidgetInfo)
{
WidgetUpdateRequestOptions updateOptions = new WidgetUpdateRequestOptions(localWidgetInfo.widgetId);
string? templateJson = null;
if (localWidgetInfo.widgetName == "Weather_Widget")
{
templateJson = weatherWidgetTemplate.ToString();
}
else if (localWidgetInfo.widgetName == "Counting_Widget")
{
templateJson = countWidgetTemplate.ToString();
}
string? dataJson = null;
if (localWidgetInfo.widgetName == "Weather_Widget")
{
dataJson = "{}";
}
else if (localWidgetInfo.widgetName == "Counting_Widget")
{
dataJson = "{ \"count\": " + localWidgetInfo.customState.ToString() + " }";
}
updateOptions.Template = templateJson;
updateOptions.Data = dataJson;
updateOptions.IsPlaceholderContent = localWidgetInfo.widgetName == "Weather_Widget";
// You can store some custom state in the widget service that you will be able to query at any time.
updateOptions.CustomState= localWidgetInfo.customState.ToString();
WidgetManager.GetDefault().UpdateWidget(updateOptions);
}
Állítsa a(z) WidgetUpdateRequestOptions.IsPlaceholderContent értékét true értékre olyan tartalom esetén, amely még nem személyre szabott vagy nem használható. A minta időjárási widgetje rögzített helyet jelenít meg, ezért ez a példa helyőrző tartalomként jelöli meg. A gazdagép előnyben részesítheti a testre szabott tartalommal rendelkező widgeteket e mintaidőjárás-widget helyett. Állítsa a tulajdonságot false értékre, amikor személyre szabott tartalmat ad meg. Ez a tulajdonság a Windows App SDK 1.6.6 verzióban lett hozzáadva.
Az engedélyezett widgetek listájának inicializálása indításkor
A widget-szolgáltató első inicializálásakor érdemes megkérdezni a WidgetManagert , hogy vannak-e futó widgetek, amelyeket a szolgáltató jelenleg kiszolgál. Segít helyreállítani az alkalmazást az előző állapotba a számítógép újraindítása vagy a szolgáltató összeomlása esetén. Hívja meg a WidgetManager.GetDefault parancsot az alkalmazás alapértelmezett widget-kezelő példányának lekéréséhez. Ezután hívja meg a GetWidgetInfos parancsot, amely WidgetInfo-objektumok tömbét adja vissza. Másolja át a widget ID-ket, neveket és egyéni állapotokat a segítő struktúrába CompactWidgetInfo, és mentse el a RunningWidgets tagváltozóba. Illessze be a következő kódot a WidgetProvider osztály osztálydefiníciójába.
// WidgetProvider.cs
public WidgetProvider()
{
var runningWidgets = WidgetManager.GetDefault().GetWidgetInfos();
foreach (var widgetInfo in runningWidgets)
{
var widgetContext = widgetInfo.WidgetContext;
var widgetId = widgetContext.Id;
var widgetName = widgetContext.DefinitionId;
var customState = widgetInfo.CustomState;
if (!RunningWidgets.ContainsKey(widgetId))
{
CompactWidgetInfo runningWidgetInfo = new CompactWidgetInfo() { widgetId = widgetId, widgetName = widgetName };
if (!string.IsNullOrEmpty(customState))
{
if (int.TryParse(customState, out int count))
{
runningWidgetInfo.customState = count;
}
else
{
Console.Error.WriteLine($"Invalid saved count for widget {widgetId}; resetting to 0.");
}
}
RunningWidgets[widgetId] = runningWidgetInfo;
}
}
}
Implementáljon egy osztály-előállítót, amely kérésre példányosítani fogja a WidgetProvidert
Ahhoz, hogy a widget-gazdagép kommunikálhasson a widget-szolgáltatóval, meg kell hívnunk a CoRegisterClassObject parancsot. Ehhez a függvényhez létre kell hoznunk az IClassFactory implementációját, amely létrehoz egy osztályobjektumot a WidgetProvider osztályhoz. Az osztálygyárat egy önálló segédosztályban fogjuk megvalósítani.
A Visual Studio kattintson a jobb gombbal a ExampleWidgetProvider projektre Megoldáskezelő, majd válassza a Add->Class lehetőséget. Az Osztály hozzáadása párbeszédpanelen nevezze el az osztályt "FactoryHelper"-nek, majd kattintson a Hozzáadásgombra.
Cserélje le a FactoryHelper.cs fájl tartalmát a következő kódra. Ez a kód meghatározza az IClassFactory felületet, és implementálja annak két metódusát, a CreateInstance-t és a LockServert. Ez a kód tipikus sablon egy osztály-előállító implementálásához, és nem jellemző a widget-szolgáltató működésére, csak azt jelzi, hogy a létrehozott osztályobjektum implementálja az IWidgetProvider interfészt.
// FactoryHelper.cs
using Microsoft.Windows.Widgets.Providers;
using System.Runtime.InteropServices;
using WinRT;
namespace COM
{
static class Guids
{
public const string IClassFactory = "00000001-0000-0000-C000-000000000046";
public const string IUnknown = "00000000-0000-0000-C000-000000000046";
}
///
/// IClassFactory declaration
///
[ComImport, ComVisible(false), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid(COM.Guids.IClassFactory)]
internal interface IClassFactory
{
[PreserveSig]
int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
[PreserveSig]
int LockServer(bool fLock);
}
[ComVisible(true)]
class WidgetProviderFactory<T> : IClassFactory
where T : IWidgetProvider, new()
{
public int CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
{
ppvObject = IntPtr.Zero;
if (pUnkOuter != IntPtr.Zero)
{
return CLASS_E_NOAGGREGATION;
}
IntPtr provider = IntPtr.Zero;
try
{
provider = MarshalInspectable<IWidgetProvider>.FromManaged(new T());
return Marshal.QueryInterface(provider, in riid, out ppvObject);
}
catch (Exception exception)
{
Console.Error.WriteLine(exception);
return Marshal.GetHRForException(exception);
}
finally
{
if (provider != IntPtr.Zero)
{
Marshal.Release(provider);
}
}
}
int IClassFactory.LockServer(bool fLock)
{
return 0;
}
private const int CLASS_E_NOAGGREGATION = -2147221232;
}
}
A widget szolgáltató CLSID azonosítóját képviselő GUID létrehozása
Ezután létre kell hoznia egy GUID-t, amely a CLSID és képvisel, és amely a widgetszolgáltató azonosítására szolgál a COM aktiválásához. Ugyanezt az értéket fogja használni az alkalmazás csomagolásakor is. Visual Studio-ban GUID létrehozása az Eszközök->GUID létrehozása menüpont segítségével. Válassza a beállításjegyzék formátumbeállítását, és kattintson a Másolás gombra, majd illessze be azt egy szövegfájlba, hogy később másolhassa.
A widget-szolgáltató osztály objektumának regisztrálása az OLE-vel
A végrehajtható példány Program.cs fájljában meghívjuk a CoRegisterClassObjectet , hogy regisztrálja a widget-szolgáltatót az OLE-ben, hogy a widget-gazdagép kommunikáljon vele. Cserélje le a Program.cs tartalmát a következő kódra. Ez a kód importálja a CoRegisterClassObject függvényt , és meghívja azt az előző lépésben definiált WidgetProviderFactory felületen. Mindenképpen frissítse a CLSID_Factory változódeklarációt az előző lépésben létrehozott GUID használatára.
// Program.cs
using System.Runtime.InteropServices;
using ComTypes = System.Runtime.InteropServices.ComTypes;
using Microsoft.Windows.Widgets;
using ExampleWidgetProvider;
using COM;
using System;
[DllImport("kernel32.dll")]
static extern IntPtr GetConsoleWindow();
[DllImport("ole32.dll")]
static extern int CoRegisterClassObject(
[MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnk,
uint dwClsContext,
uint flags,
out uint lpdwRegister);
[DllImport("ole32.dll")] static extern int CoRevokeClassObject(uint dwRegister);
WinRT.ComWrappersSupport.InitializeComWrappers();
Guid CLSID_Factory = Guid.Parse("XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX");
var factory = new WidgetProviderFactory<WidgetProvider>();
Marshal.ThrowExceptionForHR(
CoRegisterClassObject(CLSID_Factory, factory, 0x4, 0x1, out uint cookie));
try
{
if (GetConsoleWindow() != IntPtr.Zero)
{
Console.WriteLine("Registered successfully. Press ENTER to exit.");
Console.ReadLine();
}
else
{
WidgetProvider.GetEmptyWidgetListEvent().WaitOne();
}
}
finally
{
int revokeResult = CoRevokeClassObject(cookie);
if (revokeResult < 0)
{
System.Diagnostics.Trace.TraceError($"CoRevokeClassObject failed: 0x{revokeResult:X8}");
}
GC.KeepAlive(factory);
}
Vegye figyelembe, hogy ez a példakód importálja a GetConsoleWindow függvényt annak megállapításához, hogy az alkalmazás konzolalkalmazásként fut-e, az útmutató alapértelmezett viselkedését. Ha a függvény érvényes mutatót ad vissza, hibakeresési információkat írunk a konzolra. Ellenkező esetben az alkalmazás Windows alkalmazásként fut. Ebben az esetben megvárjuk a DeleteWidget metódusban beállított eseményt, amikor az engedélyezett widgetek listája üres, majd kilépünk az alkalmazásból. A példakonzolalkalmazás Windows alkalmazássá alakításával kapcsolatos információkért lásd: A konzolalkalmazás átalakítása Windows alkalmazássá.
Megjegyzés:
Az utolsó widget törlésére való várakozás egy egyszerűsített élettartam-szabályzat ebben a példában, nem pedig az IWidgetProvider követelménye. A hoszt aktiválhat és feloldhat egy szolgáltatót, miközben a widgetek rögzítve maradnak. Éles környezetű szolgáltató esetén önállóan kezelheti a COM-kiszolgáló élettartamát, visszaállíthatja a mentett widget állapotát indításkor, és szinkronizálhatja a megosztott állapothoz való hozzáférést, ha a visszahívások egyidejűleg futnak. Lásd az IWidgetProvider megjegyzéseit.
Csomagolja a widget-szolgáltató alkalmazást
Ez az útmutató egy MSIX-csomagjegyzéken keresztül regisztrálja az asztali widget-szolgáltatót, és a Windows App SDK futtatókörnyezet keretrendszerfüggő üzembe helyezését használja. Az alábbi lépések becsomagolják az alkalmazást, és regisztrálják annak providerét. Ha inkább önálló üzembe helyezést választ, kövesse a(z) Önálló alkalmazások üzembe helyezése című útmutatót, beleértve a Windows Application Packaging Project használatakor mindkét projekt beállításait.
MSIX csomagolási projekt létrehozása
A Megoldáskezelő kattintson a jobb gombbal a megoldásra, és válassza a Add->Új Project... . A Az új project párbeszédpanelen válassza az "Windows Alkalmazáscsomagoló Project" sablont, és kattintson a Next elemre. Állítsa a projekt nevét "ExampleWidgetProviderPackage" értékre, majd kattintson a létrehozása gombra. Amikor a rendszer kéri, állítsa a célverziót az 1809-es vagy újabb verzióra, és kattintson az OK gombra.
Ezután kattintson a jobb gombbal az ExampleWidgetProviderPackage projektre, és válassza a
Windows App SDK csomaghivatkozás hozzáadása a csomagolási projekthez
Az MSIX csomagolási projekthez hozzá kell adnia egy hivatkozást a Windows App SDK nuget-csomaghoz. A Megoldáskezelő kattintson duplán az ExampleWidgetProviderPackage projektre az ExampleWidgetProviderPackage.wapproj fájl megnyitásához. Adja hozzá a következő xml-t a Project elemhez.
<!--ExampleWidgetProviderPackage.wapproj-->
<ItemGroup>
<PackageReference Include="Microsoft.WindowsAppSDK" Version="2.5.1">
<IncludeAssets>build</IncludeAssets>
</PackageReference>
</ItemGroup>
Megjegyzés:
A kódrészlet a 2.5.1-es verziót használja, nem pedig a widget API-kat bevezető minimális verziót. Ha az előző lépésben egy későbbi támogatott stabil verziót választott, frissítse a Verzió értéket, hogy megfeleljen annak.
A csomagjegyzék frissítése
A Megoldáskezelő kattintson a jobb gombbal a Package.appxmanifest fájlra, és válassza a View Code lehetőséget a jegyzék xml-fájljának megnyitásához. Ezután hozzá kell adnia néhány névtér-deklarációt a használni kívánt alkalmazáscsomag-bővítményekhez. Adja hozzá a következő névtérdefiníciókat a legfelső szintű csomagelemhez .
<!-- Package.appmanifest -->
<Package
...
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
Az Alkalmazáselemen belül hozzon létre egy új üres, Bővítmények nevű elemet. Győződjön meg arról, hogy ez a uap:VisualElementszáró címkéje után jelenik meg.
<!-- Package.appxmanifest -->
<Application>
...
<Extensions>
</Extensions>
</Application>
Az első bővítmény, amelyet hozzá kell adnunk, a ComServer bővítmény. Ez regisztrálja a végrehajtható fájl belépési pontját az operációs rendszeren. Ez a bővítmény a COM-kiszolgáló regisztrációs kulcs beállításával történő regisztrálásával egyenértékű csomagolt alkalmazás, és nem a widget-szolgáltatókra vonatkozik. Adja hozzá a következő com:Extension elemet a Bővítmények elem gyermekelemeként. Módosítsa a Id attribútum GUID-ját a com:Class elemben arra a GUID-ra, amelyet az előző lépésben generált.
<!-- Package.appxmanifest -->
<Extensions>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="ExampleWidgetProvider\ExampleWidgetProvider.exe" DisplayName="ExampleWidgetProvider">
<com:Class Id="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" DisplayName="ExampleWidgetProvider" />
</com:ExeServer>
</com:ComServer>
</com:Extension>
</Extensions>
Ezután adja hozzá az alkalmazást widget-szolgáltatóként regisztráló bővítményt. Illessze be a uap3:Extension elemet a következő kódrészletbe, a Bővítmények elem gyermekeként. Mindenképpen cserélje le a COM-elemClassId attribútumát az előző lépésekben használt GUID azonosítóra.
<!-- Package.appxmanifest -->
<Extensions>
...
<uap3:Extension Category="windows.appExtension">
<uap3:AppExtension Name="com.microsoft.windows.widgets" DisplayName="WidgetTestApp" Id="ContosoWidgetApp" PublicFolder="Public">
<uap3:Properties>
<WidgetProvider>
<ProviderIcons>
<Icon Path="Images\StoreLogo.png" />
</ProviderIcons>
<Activation>
<!-- Apps exports COM interface which implements IWidgetProvider -->
<CreateInstance ClassId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" />
</Activation>
<TrustedPackageFamilyNames>
<TrustedPackageFamilyName>Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe</TrustedPackageFamilyName>
</TrustedPackageFamilyNames>
<Definitions>
<Definition Id="Weather_Widget"
DisplayName="Weather Widget"
Description="Weather Widget Description"
AllowMultiple="true">
<Capabilities>
<Capability>
<Size Name="small" />
</Capability>
<Capability>
<Size Name="medium" />
</Capability>
<Capability>
<Size Name="large" />
</Capability>
</Capabilities>
<ThemeResources>
<Icons>
<Icon Path="ProviderAssets\Weather_Icon.png" />
</Icons>
<Screenshots>
<Screenshot Path="ProviderAssets\Weather_Screenshot.png" DisplayAltText="For accessibility" />
</Screenshots>
<!-- DarkMode and LightMode are optional -->
<DarkMode />
<LightMode />
</ThemeResources>
</Definition>
<Definition Id="Counting_Widget"
DisplayName="Microsoft Counting Widget"
Description="Counting Widget Description">
<Capabilities>
<Capability>
<Size Name="small" />
</Capability>
</Capabilities>
<ThemeResources>
<Icons>
<Icon Path="ProviderAssets\Counting_Icon.png" />
</Icons>
<Screenshots>
<Screenshot Path="ProviderAssets\Counting_Screenshot.png" DisplayAltText="For accessibility" />
</Screenshots>
<!-- DarkMode and LightMode are optional -->
<DarkMode>
</DarkMode>
<LightMode />
</ThemeResources>
</Definition>
</Definitions>
</WidgetProvider>
</uap3:Properties>
</uap3:AppExtension>
</uap3:Extension>
</Extensions>
Az összes elem részletes leírását és formátuminformációit lásd itt: Widget provider package manifest XML format.
Ikonok és egyéb képek hozzáadása a csomagolási projekthez
A Megoldáskezelő-ben kattintson a jobb egérgombbal a ExampleWidgetProviderPackage-re, majd válassza az > lehetőséget. Nevezze el ezt a mappát ProviderAssets néven, mivel ez volt az Package.appxmanifest előző lépésben használt mappa. Itt fogjuk tárolni a widgetek ikonjait és képernyőképeit . Miután hozzáadta a kívánt ikonokat és képernyőképeket, győződjön meg arról, hogy a képnevek megegyeznek a Path=ProviderAssets\ után található névvel a Package.appxmanifest-ben, különben a widgetek nem fognak megjelenni a widgetgazdagépen.
A képernyőképképek tervezési követelményeivel és a honosított képernyőképek elnevezési konvencióival kapcsolatos információkért lásd: Integrálás a vezérlőválasztóval.
A widget-szolgáltató tesztelése
Válassza ki a fejlesztői gépnek megfelelő architektúrát a Megoldásplatformok legördülő listából, például "x64". A Megoldáskezelőben kattintson a jobb gombbal a megoldásra, és válassza a Megoldás fordítása parancsot, majd kattintson a jobb gombbal az ExampleWidgetProviderPackage elemre, és válassza az Üzembe helyezés lehetőséget. Windows 11-ben nyissa meg a widgetek tábláját Windows+W billentyűkombinációval, nyissa meg a widgetválasztót, és keresse meg a Weather Widget és Microsoft Counting Widget. Adja hozzá őket a boardhoz, és tesztelje a működésüket. A választóvezérlők és elhelyezésük a Windows és a Widgets Board frissítéseitől függően változhat.
Az Adaptív kártyák Tervező nem biztosít Windows $host értékeket, nem hívja meg a szolgáltató callbackjeit, és nem kényszeríti ki a Widgets Board megjelenített korlátait. Végezze el ezeket az ellenőrzéseket a Widgets Boardban:
- Győződjön meg arról, hogy a widget megjelenik a választóban a várt névvel, ikonnal, képernyőképtel és leírással.
- Rögzítse a widgetet, és ellenőrizze annak kezdeti sablonját és adatait.
- Méretezze át a csomagjegyzékben deklarált összes méretre. Ellenőrizze, hogy minden méretben vannak-e levágott, rejtett vagy túlcsorduló tartalmak.
- Tesztelje az egyes Action.Execute műveletet, ha
$host.isUserContextAuthenticatedigaz. Ha hamis, rejtse el a nem támogatott műveleteket, és biztosítson megfelelő alternatívát; ebben a környezetben csak az Action.OpenUrl támogatott. - Állítsa le és indítsa újra a szolgáltatói folyamatot, majd ellenőrizze, hogy az egyes rögzített widgetek visszaállnak-e a saját egyéni állapotukból.
- Szüntesse meg a widget rögzítését, és győződjön meg arról, hogy DeleteWidget meghívódik.
A jelen útmutatóban szereplő különálló csomagolási projekt helyett egyprojektes MSIX-et használó CLI-első C#-projekt esetén helyezzen a Package.appxmanifest szolgáltatói projektbe, állítsa a(z) true értékét erre: EnableMsixTooling, és használja a Windows-alkalmazás fejlesztési cli-t egy fejlesztési csomag összeállításához és regisztrálásához:
Important
A Windows-alkalmazás fejlesztési parancssori felület jelenleg közzétételi előzetes verzióban érhető el. A funkciók és a parancsok a végleges kiadás előtt változhatnak. A parancs használata előtt ellenőrizze a telepített verzió winapp run --help kimenetét.
winapp run ExampleWidgetProvider.csproj --configuration Release --arch x64 --no-launch
A parancs az alkalmazás közvetlen elindítása nélkül regisztrálja a csomagot. A COM-kiszolgáló widget-gazdagépen keresztüli aktiválásához nyissa meg a Widgets Boardot.
A widget-szolgáltató hibakeresése
Miután rögzítette a widgeteket, a widgetplatform elindítja a widget-szolgáltató alkalmazást, hogy releváns információkat kapjon és küldjön a widgetről. A futó widget hibakereséséhez csatolhat egy hibakeresőt a futó widget-szolgáltató alkalmazáshoz, vagy beállíthatja, hogy Visual Studio automatikusan elindítsa a widget-szolgáltatói folyamat hibakeresését az indítás után.
A futó folyamathoz való csatoláshoz:
- A Visual Studio kattintson a Debug -> Csatolás a folyamathoz elemre.
- Szűrje a folyamatokat, és keresse meg a kívánt widgetszolgáltatói alkalmazást.
- Csatold a hibakeresőt.
Annak érdekében, hogy a hibakereső automatikusan csatolva legyen a folyamathoz az első indításkor:
- A Visual Studio kattintson a Debug -> Egyéb hibakeresési célok -> Telepített alkalmazáscsomag hibakeresése elemre.
- Szűrje a csomagokat, és keresse meg a kívánt widget-szolgáltatói csomagot.
- Válassza ki, és jelölje be a jelölőnégyzetet, amelynek szövege: "Ne induljon el, de végezzen hibakeresést, amikor a kód elindul".
- Kattintson az ésCsatolás gombra.
Konzolalkalmazás átalakítása Windows alkalmazássá
Az ebben az útmutatóban létrehozott konzolalkalmazás Windows alkalmazássá alakításához kattintson a jobb gombbal a ExampleWidgetProvider projektre a Megoldáskezelő> és válassza a Properties lehetőséget. Az Application->General területen módosítsa a Output típust a "Konzolalkalmazás" típusról "Windows alkalmazásra".
Projektfájl szerkesztése esetén állítsa az OutputType értékét a következőre WinExe:
<OutputType>WinExe</OutputType>
Ezt a végső felhasználói élmény ellenőrzése vagy közzététele előtt tegye meg. A konzolszolgáltató megnyithat egy terminálablakot, amikor a widget-gazdagép aktiválja a COM-kiszolgálóját.
A widget közzététele
Miután kifejlesztette és tesztelte a widgetet, közzéteheti az alkalmazást a Microsoft Store annak érdekében, hogy a felhasználók telepíthessék a widgeteket az eszközeikre. Az alkalmazások közzétételével kapcsolatos részletes útmutatásért lásd: Az alkalmazás közzététele a Microsoft Store.
A widgetek áruházgyűjteménye
Miután közzétette az alkalmazást a Microsoft Store, kérheti, hogy az alkalmazás szerepeljen a widgetek áruházgyűjteményében, amely segít a felhasználóknak az Windows widgeteket használó alkalmazások felderítésében. A kérés elküldéséhez lásd: a widget adatainak benyújtása a Store gyűjteményhez való hozzáadáshoz.
Widget testreszabásának megvalósítása
A Windows App SDK 1.4-től kezdve a widgetek támogatják a felhasználók testreszabását. A funkció megvalósításakor a rendszer hozzáad egy testreszabási widget-beállítást a vezérlő rögzítésének feloldása lehetőség feletti három pont menühöz.
Az alábbi lépések összefoglalják a widget testreszabásának folyamatát.
- Szokásos működés során a widget-szolgáltató válaszol a widget-gazdagéptől érkező kérésekre a sablonnal és az adatokkal a normál widget-élmény érdekében.
- A felhasználó az ellipszis menüben a Widget testreszabása gombra kattint.
- A widget az OnCustomizationRequested eseményt a widget-szolgáltatón jelzi, hogy a felhasználó kérte a widget testreszabási felületét.
- A widget-szolgáltató beállít egy belső jelzőt, amely jelzi, hogy a widget testreszabási módban van. Testreszabási módban a widget-szolgáltató a szokásos widget-felhasználói felület helyett elküldi a widget testreszabási felhasználói felületéhez tartozó JSON-sablonokat.
- Testreszabási módban a widget-szolgáltató onActionInvoked eseményeket fogad, miközben a felhasználó interakcióba lép a testreszabási felhasználói felülettel, és a felhasználó műveletei alapján módosítja annak belső konfigurációját és viselkedését.
- Ha az OnActionInvoked eseményhez társított művelet az alkalmazás által definiált "kilépés testreszabása" művelet, a widget-szolgáltató visszaállítja a belső jelzőt, hogy jelezze, hogy már nincs testreszabási módban, és folytatja a vizualizációs és adat JSON-sablonok küldését a szokásos widget-élmény érdekében, a testreszabás során kért módosításoknak megfelelően. A felhasználó bezárhatja a testreszabási felületet anélkül, hogy az alkalmazás által meghatározott kilépési testreszabási műveletre kattintanak. Ebben az esetben aktiválódik az IWidgetProviderAnalytics.OnAnalyticsInfoReported, és a WidgetAnalyticsInfoReportedArgs.AnalyticsJson "exitCustomization" típusú interakcióval rendelkezik.
- A widget-szolgáltató megőrzi a lemez vagy a felhő testreszabási beállításait, hogy a módosítások megmaradjanak a widget-szolgáltató meghívásai között.
Megjegyzés:
A Windows widgettáblában ismert hiba lép fel a Windows App SDK használatával létrehozott widgetek esetében, amely miatt a három pont menü nem válaszol a testreszabási kártya megjelenítése után.
A widgetek tipikus testreszabási forgatókönyveiben a felhasználó kiválaszthatja, hogy milyen adatok jelenjenek meg a widgeten, vagy módosíthatja a widget vizuális megjelenítését. Az egyszerűség kedvéért az ebben a szakaszban szereplő példa olyan testreszabási viselkedést ad hozzá, amely lehetővé teszi, hogy a felhasználó visszaállítsa az előző lépésekben implementált számláló widget számlálóját.
Megjegyzés:
A widget testreszabásához 1.4-Windows App SDK vagy újabb verzió szükséges. Ez az útmutató a Microsoft.WindowsAppSDK 2.5.1-es verzióját használja.
A csomagjegyzék frissítése a testreszabási támogatás deklarálásához
Ha tudatni szeretné a widget gazdagépével, hogy a widget támogatja a testreszabást, adja hozzá az IsCustomizable attribútumot a widget Definíció eleméhez, és állítsa igaz értékre.
...
<Definition Id="Counting_Widget"
DisplayName="Microsoft Counting Widget"
Description="CONFIG counting widget description"
IsCustomizable="true">
...
Nyomon követheti, ha egy widget testreszabási módban van
A cikkben szereplő példa a CompactWidgetInfo segédstruktúra segítségével követi nyomon az aktív widgetek aktuális állapotát. Adja hozzá az inCustomization mezőt, amely nyomon követi, hogy a widget-gazdagép mikor várja, hogy elküldjük a testreszabási JSON-sablont a szokásos widgetsablon helyett.
// WidgetProvider.cs
public class CompactWidgetInfo
{
public string widgetId { get; set; }
public string widgetName { get; set; }
public int customState = 0;
public bool isActive = false;
public bool inCustomization = false;
}
IWidgetProvider2 implementálása
A widget testreszabási funkciója az IWidgetProvider2 felületen keresztül érhető el. Frissítse a WidgetProvider osztálydefiníciót a felület implementálásához.
// WidgetProvider.cs
internal class WidgetProvider : IWidgetProvider, IWidgetProvider2
Adjon hozzá egy implementációt az IWidgetProvider2 felület OnCustomizationRequested visszahívásához. Ez a módszer ugyanazt a mintát használja, mint a többi használt visszahívás. Lekérjük a widget testreszabásához szükséges azonosítót a WidgetContextből , és megkeresjük a widgethez társított CompactWidgetInfo segédszerkezetet, és igaz értékre állítjuk az inCustomization mezőt.
// WidgetProvider.cs
public void OnCustomizationRequested(WidgetCustomizationRequestedArgs customizationInvokedArgs)
{
var widgetId = customizationInvokedArgs.WidgetContext.Id;
if (RunningWidgets.ContainsKey(widgetId))
{
var localWidgetInfo = RunningWidgets[widgetId];
localWidgetInfo.inCustomization = true;
UpdateWidget(localWidgetInfo);
}
}
Most deklaráljon egy sztringváltozót, amely meghatározza a widget testreszabási felhasználói felületéhez tartozó JSON-sablont. Ebben a példában az "Alaphelyzetbe állítás számláló" gomb és a "Kilépés a testreszabásból" gomb jelzi a szolgáltatónknak, hogy térjen vissza a szokásos widget-működéshez. Helyezze ezt a definíciót a többi sablondefiníció mellé.
// WidgetProvider.cs
const string countWidgetCustomizationTemplate = @"
{
""type"": ""AdaptiveCard"",
""actions"" : [
{
""type"": ""Action.Execute"",
""title"" : ""Reset counter"",
""verb"": ""reset""
},
{
""type"": ""Action.Execute"",
""title"": ""Exit customization"",
""verb"": ""exitCustomization""
}
],
""$schema"": ""http://adaptivecards.io/schemas/adaptive-card.json"",
""version"": ""1.5""
}";
Testreszabási sablon küldése az UpdateWidgetben
Ezután frissítjük az UpdateWidget segédmetódusunkat, amely elküldi az adatokat és a vizuális JSON-sablonokat a widget-gazdagépnek. A számláló widget frissítésekor a szokásos widgetsablont vagy a testreszabási sablont küldjük el az inCustomization mező értékétől függően. A rövidség kedvéért a testreszabás szempontjából nem releváns kód hiányzik ebben a kódrészletben.
// WidgetProvider.cs
void UpdateWidget(CompactWidgetInfo localWidgetInfo)
{
...
else if (localWidgetInfo.widgetName == "Counting_Widget")
{
if (!localWidgetInfo.inCustomization)
{
templateJson = countWidgetTemplate.ToString();
}
else
{
templateJson = countWidgetCustomizationTemplate.ToString();
}
}
...
updateOptions.Template = templateJson;
updateOptions.Data = dataJson;
// You can store some custom state in the widget service that you will be able to query at any time.
updateOptions.CustomState = localWidgetInfo.customState.ToString();
WidgetManager.GetDefault().UpdateWidget(updateOptions);
}
Válasz a testreszabási műveletekre
Amikor a felhasználók a testreszabási sablonban lévő bemenetekkel dolgoznak, ugyanazt az OnActionInvoked kezelőt hívja meg, mint amikor a felhasználó a szokásos vezérlőélményt használja. A testreszabás támogatása érdekében a testreszabási JSON-sablonban az "reset" és "exitCustomization" igéket keressük. A "Számláló visszaállítása" művelet alaphelyzetbe állítja a customState értékét 0-ra, és kilép a testreszabásból. A "Kilépés testreszabása" művelet a számláló alaphelyzetbe állítása nélkül lép ki. Mindkettő a inCustomization értékét hamisra állítja, így az UpdateWidget elküldi a szokásos widgetsablont.
// WidgetProvider.cs
public void OnActionInvoked(WidgetActionInvokedArgs actionInvokedArgs)
{
var verb = actionInvokedArgs.Verb;
if (verb == "inc")
{
var widgetId = actionInvokedArgs.WidgetContext.Id;
// If you need to use some data that was passed in after
// Action was invoked, you can get it from the args:
var data = actionInvokedArgs.Data;
if (RunningWidgets.ContainsKey(widgetId))
{
var localWidgetInfo = RunningWidgets[widgetId];
// Increment the count
localWidgetInfo.customState++;
UpdateWidget(localWidgetInfo);
}
}
else if (verb == "reset")
{
var widgetId = actionInvokedArgs.WidgetContext.Id;
var data = actionInvokedArgs.Data;
if (RunningWidgets.ContainsKey(widgetId))
{
var localWidgetInfo = RunningWidgets[widgetId];
// Reset the count
localWidgetInfo.customState = 0;
localWidgetInfo.inCustomization = false;
UpdateWidget(localWidgetInfo);
}
}
else if (verb == "exitCustomization")
{
var widgetId = actionInvokedArgs.WidgetContext.Id;
var data = actionInvokedArgs.Data;
if (RunningWidgets.ContainsKey(widgetId))
{
var localWidgetInfo = RunningWidgets[widgetId];
// Stop sending the customization template
localWidgetInfo.inCustomization = false;
UpdateWidget(localWidgetInfo);
}
}
}
Most, amikor üzembe helyezi a widgetet, látnia kell a Widget testreszabása gombot a három pont menüben. A testreszabás gombra kattintva megjelenik a testreszabási sablon.
A Számláló alaphelyzetbe állítása gombra kattintva állítsa vissza a számlálót 0-ra. Kattintson a Kilépés a testreszabásból gombra a widget szokásos viselkedéséhez való visszatéréshez.
Windows developer