Read more of this story at Slashdot.
Read more of this story at Slashdot.
Read more of this story at Slashdot.
Last year Microsoft introduced Phi Silica and recently made an experimental release of the Windows App Sdk that can be used by Windows application to interact with Phi Silica. In this post we’ll connect an Uno Platform application to Phi Silica.
We’ll keep things simple and start with the Blank preset in the Uno Platform template wizard and add Mvvm support under the Presentation section.
In order to access the Phi Silica apis we’ll first need to update to the experimental release of the Windows App Sdk. With Uno, this is done by setting the WinAppSdkVersion
property to the experimental version, 1.7.250127003-experimental3.
<PropertyGroup Condition="'$(TargetFramework)'=='net9.0-windows10.0.26100'">
<WinAppSdkVersion>1.7.250127003-experimental3</WinAppSdkVersion>
</PropertyGroup>
The Phi Silica apis won’t appear whilst the Platform of the project is set to AnyCPU. To resolve this, we need to set both the Platforms and RuntimeIdentifiers properties, when the application is targeting Windows.
<PropertyGroup Condition="'$(TargetFramework)'=='net9.0-windows10.0.26100'">
<Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<WinAppSdkVersion>1.7.250127003-experimental3</WinAppSdkVersion>
</PropertyGroup>
After making this adjustment, open Configuration Manager and make sure the Platform value is set to the correct architecture.
Let’s add a MainViewModel that will be used to send a message to Phi Silica and get a response.
using Microsoft.UI.Xaml.Data;
#if WINDOWS
using Microsoft.Windows.AI.Generative;
#endif
namespace PhiMessagingApp;
[Bindable]
public partial class MainViewModel : ObservableObject
{
[ObservableProperty]
private string _response = string.Empty;
[RelayCommand]
public async Task SendMessage(string message)
{
#if WINDOWS
if (!LanguageModel.IsAvailable())
{
var op = await LanguageModel.MakeAvailableAsync();
}
using LanguageModel languageModel = await LanguageModel.CreateAsync();
var result = await languageModel.GenerateResponseAsync(message);
Response = result.Response;
#else
Response = "Design-time response....";
#endif
}
}
Next we’ll set an instance of the MainViewModel
as the DataContext on the MainPage.
public MainPage()
{
this.InitializeComponent();
DataContext = new MainViewModel();
}
Whilst the Phi Silica APIs only work on Windows, for the purpose of designing the interface we’ll switch target to Desktop.
We’ll run the application and should see both Hot Design and Hot Reload buttons in the floating toolbar.
Clicking the Hot Design (left) button will enter the design experience. We’ll keep things simple by adding a TextBox (message input), Button (to invoke the SendMessage method) and TextBlock (response output). The following video shows adding these elements along with databinding the elements.
Now, with everything wired up we can switch back to the PhiMessagingApp (WinAppSDK Packaged)
target.
Unfortunately, at this point you’ll likely run into the following exception:
System.Runtime.InteropServices.COMException: 'Interface not registered
Failed to find proxy registration for IID: {EBF3748D-1EF9-4B89-BA13-65D2B9EC04F0}.'
This exception is a result of the application running as self-contained, which is not supported by the experimental release, as noted in the docs.
Luckily, there’s a quick fix. We can adjust the WindowsAppSDKSelfContained
property to false, which will resolve this issue.
<PropertyGroup Condition="'$(TargetFramework)'=='net9.0-windows10.0.26100'">
<Platforms>x86;x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
<WinAppSdkVersion>1.7.250127003-experimental3</WinAppSdkVersion>
<WindowsAppSDKSelfContained>false</WindowsAppSDKSelfContained>
</PropertyGroup>
Let’s go ahead and run the application and enter a prompt, “Why is the sky blue”, and see the response.
As you can see from this post, it’s easy to reference Phi Silca from an Uno Platform application. Whilst the APIs are for Windows only, this can be used to light up your cross platform application with locally executing AI when running on Windows.
The post AI on Windows: Chatting with Phi Silica appeared first on Nick's .NET Travels.
I think I may have an alternative approach to make the deregionization solution-wide...
Welcome back, htmx explorer. Today, we’re unlocking two of the most powerful tools in the htmx toolbox: hx-target and hx-swap. These are the keys to making your Razor Pages do precisely what you want without breaking a sweat.
When building interactive web pages, you don’t always want to replace the entire page every time you fetch new content. Sometimes, you want to update a small part of the page, like a form or a specific component. That’s where hx-target and hx-swap come in.
Let’s break down how these features work and see some real-world use cases.
The hx-target attribute tells htmx where to place the response from a request. By default, htmx replaces the element that triggered the request, but you can specify any element you want.
Imagine you have a button that fetches user details without refreshing the page.
@page @model IndexModel <!DOCTYPE html> <html> <head> <title>htmx Targeting Demo</title> <script src="https://unpkg.com/htmx.org"></script> </head> <body> <h1>User Details</h1> <div id="user-info"> <button hx-get="/Index?handler=GetUser" hx-target="#user-info">Load User Info</button> </div> </body> </html>
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace YourNamespace.Pages; public class IndexModel : PageModel { public IActionResult OnGetGetUser() { var userHtml = "<div><p>Name: John Doe</p><p>Age: 30</p></div>"; return Content(userHtml, "text/html"); } }
What’s happening here? The button sends a request to /GetUser
, and the result is injected into the #user-info
div because of the hx-target attribute. Simple and effective.
Now let’s talk about hx-swap. It controls how the response is inserted into the target element. Here are your options:
outerHTML
(Default): Replaces the entire target element.innerHTML
: Replaces only the contents of the target element.beforebegin
: Inserts content before the target element.afterbegin
: Inserts content inside the target element, before existing content.beforeend
: Inserts content inside the target element, after existing content.afterend
: Inserts content after the target element.Suppose you have a list of items you want to update without replacing the entire list.
@page @model IndexModel <!DOCTYPE html> <html> <head> <title>htmx Swapping Demo</title> <script src="https://unpkg.com/htmx.org"></script> </head> <body> <h1>Item List</h1> <div id="item-list"> <button hx-get="/Index?handler=AddItem" hx-swap="beforeend" hx-target="#item-list">Add Item</button> <div>Item 1</div> <div>Item 2</div> </div> </body> </html>
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace YourNamespace.Pages; public class IndexModel : PageModel { private static int _itemCount = 2; public IActionResult OnGetAddItem() { _itemCount++; var newItemHtml = $"<div>Item {_itemCount}</div>"; return Content(newItemHtml, "text/html"); } }
In this example, hx-swap="beforeend"
ensures that every time you click the button, a new item is added to the end of the list instead of replacing the entire list. That’s some serious power with minimal effort.
The combination of hx-target and hx-swap is ideal for all kinds of scenarios, such as:
The true power of htmx lies in mixing and matching attributes to make your web apps more interactive without overloading them with client-side logic. Swapping and targeting with htmx is one of the simplest ways to improve your user experience with very little code.
Next up, we’ll be building full-fledged interactive applications where these techniques really shine. Stay tuned.
The post Swapping and Targeting Like a Pro: htmx Magic for Razor Pages appeared first on Chris Woody Woodruff.