levitali / compiledbindings Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Is it possible to implement markup extension {x:Uid ...}
in WPF? Or any alternative to it to achieve?
When meeting the needs of globalization, I feel like that {x:Uid ...}
works well along with .resw files.
Is it possible to add support to Avalonia UI ?
Thank you
Hi,
In a MAUI app, I've managed to use x:Bind pretty much everywhere I need it.
Except when the binding is for a LongPressCommand (from the https://github.com/vapolia/MauiGestures lib).
Here is a link to a simple repro project: repro
Here is the code that triggers a build error:
<?xml version="1.0" encoding="utf-8" ?>
<Button
x:Class="MauiAppTestCompiledBindings.MyButton"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiAppTestCompiledBindings"
xmlns:mauiGestures="clr-namespace:MauiGestures;assembly=MauiGestures"
mauiGestures:Gesture.LongPressCommand="{x:Bind ClickCommand}"
x:DataType="local:MainViewModel"
Text="Click me" />
Here is the build error message:
error CS1503: Argument 1: cannot convert from 'MauiAppTestCompiledBindings.MyButton.MyButton_Bindings_this' to 'Microsoft.Maui.Controls.BindableObject'
Could you please take a look and tell me if you think this is something that can be fixed, either in my code, or in the CompiledBindings library, or in the MauiGesture library?
Thank you!
I am trying to use the library in the MAUI project on macOS with net6.0 6.0.300 and the compilation fails with the next error:
CompiledBindings.MAUI.targets(82, 9): [MSB4062] The "MauiGenerateCodeTask" task could not be loaded from the assembly /Users/stanislav/.nuget/packages/compiledbindings.maui/1.0.10/build/../build/CompiledBindings.MAUI.dll. Could not load file or assembly 'Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.
Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.
The same project works fine on windows.
Source: https://github.com/byme8/expMauiCompiledBindings
Any idea what can be wrong?
I want to congratulate with the author for being the only one to take this initiative for a feature that should be part of WPF sdk.
It works great, but over the time I found a severe limitation which makes the implementation pretty much unusable: unlike UWP versiom, the markup extension only accepts one parameter when binding to a function. With mostly of the framework ones we're kicked off since only a very small amount of functions takes one parameter. With custom functions is pretty much the same as long as we need to pass more than one parameter and there is no hack that works (tuples, class instance with its properties as parameters etc).
Is this something difficult to implement?
I also found big problems with async functions. The markup extension does not accept a return type of Task and I've not been able to find a way to run any async code. Regular Bindings deals with this through IsAsync property. Something like this would be good or, even better, the ability to accept "await" keyword.
Other improvements:
Thanks
In a MAUI project with nullable checks enabled, including the CompiledBindings.MAUI nuget seems to override this setting and disables the nullable checks. This results in tonnes of warnings, for every .cs file that uses the ? suffix (like string? myString). FYI, an example library project could be like this:
<PropertyGroup>
<TargetFrameworks>net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net6.0-windows10.0.19041.0</TargetFrameworks>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">14.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.19041.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.19041.0</TargetPlatformMinVersion>
<AssemblyName>Gs.$(MSBuildProjectName)</AssemblyName>
<RootNamespace>Gs.$(MSBuildProjectName.Replace(" ", "_"))</RootNamespace>
<SingleProject>true</SingleProject>
<UseMaui>true</UseMaui>
<LangVersion>10.0</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CompiledBindings.MAUI" Version="1.0.11" />
</ItemGroup>
Thank you for creating this fantastic project, I hope this can be resolved easily!
This is a great library, but as far as I know custom Markup does not support intellisense and neither does this library, which makes it a bit difficult to use this library.
I'm very appreciate your work about x:bind
, it does removes whole load of boilerplate code and boost performance nicely. But at the same time, Microsoft just release its MVVM toolkit, which also use generator to generate event code when property change.
The thing is if use alone, these two librarys are fine, but when use together, i inspect and see each library generate its code to different file and not aware of the other existence, and therefor if you use bind with code gen by MVVM toolkit, x:bind
force compiler to reexecute code generator of MVVM toolkit, which then confuse compiler since those code already generated and thus it enter endless loop and crash with code -532,462,766 With no further detail or throw exception to reproduce.
// viewmodel
public class AviewModel: ObservableObject
{
// this generates a User property with setter
// SetProperty
[ObservableProperty] private User _user;
// ------some more properties----------
[RelayCommand(CanExcute= nameof(MyCheckFn)]
private async Task LoginAsync ()
{
// some logic
} // generate LoginAsyncCommand
}
\\ login.xaml
\\------ skip bunch of code
<Button Command="{x:bind ViewModel.LoginCommand}" Content="Submit"/>
\\ when build: success
\\ then run that exe : nothing happend, wait, compiler
\\ stop excuting and print
\\ process end with -523,...
While improving binding performance for regular controls is nice, the real use case for me would be, to use compiled bindings in styles with datatriggers, so that i can update the UI on state changes.
Example:
<DataTemplate DataType="{x:Type local:DataEntryViewModel}">
<Rectangle Width="10"
Height="10"
Margin="1">
<Rectangle.Style>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Fill" Value="Gray" />
<Setter Property="ToolTip" Value="Not Loaded" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoaded}" Value="True">
<Setter Property="Fill" Value="Green" />
<Setter Property="ToolTip" Value="Loaded" />
</DataTrigger>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<Setter Property="Fill" Value="Red" />
<Setter Property="ToolTip" Value="Busy" />
</DataTrigger>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter Property="Fill" Value="Blue" />
<Setter Property="ToolTip">
<Setter.Value>
<ToolTip>
<TextBlock>
<Run Text="{Binding IsLoaded, StringFormat={}IsLoaded: {0}, Mode=OneWay}" />
<LineBreak />
<Run Text="{Binding IsBusy, StringFormat={}IsBusy: {0}, Mode=OneWay}" />
<LineBreak />
<Run Text="{Binding IsActive, StringFormat={}IsActive: {0}, Mode=OneWay}" />
</TextBlock>
</ToolTip>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</DataTemplate>
I dont think this is currently supported. Feel free to correct me otherwise.
Could you add support for WinUI 3?
Thanks :)
Hello,
I'm not sure on what could be the source of the problem, but I believe it should be given a look at x:bind since the problem does not occur with default binding. I have attached here a sample project which is composed of 3 buttons.
The second button change visibility of the third button from visible to hidden and viceversa.
The first button executes a custom command which basically opens a message box which inform about button 3 visibility.
For the command itself x:bind works as expected. Problem is on the CommandParamater (which pass button 3 visibility to the command). It causes the control to become disabled.
Uncomment the x:bind variant to observe this misterious behaviour.
<!--Does not work if x:bind is used for CommandParameter and the button becomes misteriously disabled-->
<Button Content="Test" Command="{x:Bind Mwv.MyCustomCommand}"
CommandParameter="{x:Bind Button3.IsVisible, Mode=OneWay}" />
<!--It works as expected when regular binding is used for CommandParameter-->
<Button Content="Get button 3 visibility" Command="{x:Bind Mwv.MyCustomCommand}"
CommandParameter="{Binding IsVisible, Source={x:Reference Button3}, Mode=OneWay}" />
I seem to have found an odd bug that occurs when using x:Bind on a control from another namespace where the end of one namespace matches the start of another namespace eg. CompiledBindingsTest.WPF and WPF.CustomControls.
The following error will occur when attempting to build:
error CS0234: The type or namespace name 'CustomControls' does not exist in the namespace 'CompiledBindingsTest.WPF' (are you missing an assembly reference?)
It's like part of the namespace is being cut off.
Please see the attached repro:
CompiledBindingsTest.zip
There are 2 WPF apps in this solution. They are the the exact same except the namespace is different.
CompiledBindingsTest will build successfully but CompiledBindingsTest.WPF will not.
Renaming the namespace to something like CompiledBindingsTest.WPF2 will allow it to build successfully.
Thanks for creating this project, I've been using it for a few days now and it's great!
First, congratulations for your library!
Is it faster than the bindings in the Xamarin Forms on Android for example? If yes, why, which are the improvements?
Thanks!
Hi,
i was trying your lib for a project of mine and found compiled bindings throwing NullRef exceptions.
Maybe you can take a look and either tell me if i'm doing something wrong, or if this is a bug.
Code: MVP can be found here
Reprosteps:
Stacktrace:
System.NullReferenceException: Object reference not set to an instance of an object.
at CompiledBindings.DataTemplateBindings.BindingsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
at System.Windows.StyleHelper.ClearTemplateChain(HybridDictionary[] instanceData, FrameworkElement feContainer, FrameworkContentElement fceContainer, List`1 templateChain, FrameworkTemplate oldFrameworkTemplate)
at System.Windows.StyleHelper.ClearGeneratedSubTree(HybridDictionary[] instanceData, FrameworkElement feContainer, FrameworkContentElement fceContainer, FrameworkTemplate oldFrameworkTemplate)
at System.Windows.StyleHelper.DoTemplateInvalidations(FrameworkElement feContainer, FrameworkTemplate oldFrameworkTemplate)
at System.Windows.Controls.ContentPresenter.OnTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.Controls.ContentPresenter.EnsureTemplate()
at System.Windows.Controls.ContentPresenter.OnPreApplyTemplate()
at System.Windows.FrameworkElement.ApplyTemplate()
at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
at System.Windows.UIElement.Measure(Size availableSize)
at System.Windows.ContextLayoutManager.UpdateLayout()
at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
Hello!
I followed the examples on the main page and everything is very easy to understand and works pretty well, except for this part:
<TextBlock m:Text="{x:Bind system:String.Format('{0:0.###} {1}', Quantity, Unit)}"/>
When I try to format a string in Xaml, I get a message that "system" cannot be resolved. In the whole documentation there is no word about how to declare this namespace so that it compiles correctly without errors.
Everything works of course if I add the following namespace:
xmlns:system="clr-namespace:System;assembly=mscorlib"
It's clear to me, but I think a lot of people without experience will have trouble figuring out what's going on here.
Regards
John
I have this line of code in WPF app
<TextBox Text="{x:Bind $'String value: {Username}'}" />
and compiler is throwing error
error MC3043: Names and Values in a MarkupExtension cannot contain quotes. The MarkupExtension arguments ' $'String value: {Username}'
I'm using VS 17.5.5 and I don't know whats the problem. Does anyone else has this problem? Am I missing something?
Hello
Is there any performance tests done vs the normal binding's?
There is an issue with C#/Roslyn Analyzers
doing analysis on the CompiledBindings generated code. Roslyn Analyzers will avoid doing analysis on code if:
File begins with auto-generated comment // <autogenerated />
.
File name starts with TemporaryGeneratedFile_
.
File name ends with .designer
, .generated
, .g
, or .g.i
right before the extension.
The current logic can be found at https://github.com/dotnet/roslyn/blob/main/src/Compilers/Core/Portable/InternalUtilities/GeneratedCodeUtilities.cs
With version 1.0.9-rc1 i get several errors during compilation, when trying to use x:Bind with an HierarchicalDataTemplate, preventing me from using it with TreeViews in WPF.
Example:
<Window.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:BusyViewModel}" ItemsSource="{x:Bind Items, IsItemsSource=true}" />
</Window.Resources>
The benefits in using x:Set are ?
when we use
Task.Run(()=>
{
A = 10;
});
throw a runtime error
Text="{x:Bind A}"
Under which license is the project?
Hello, Compiled bindings is unable to see anything inside <ControlTemplate />
Link to the repo
I looks like this
<cv:TemplatedTaskLoader x:Name="LoaderView"
Grid.Row="1"
Style="{StaticResource TemplatedLoaderLongLoading}"
TaskLoaderNotifier="{Binding Loader}">
<cv:TemplatedTaskLoader.ResultControlTemplate>
<ControlTemplate>
<ListView ItemsSource={x:Bind ViewModel.ListOfItems} /> <--- Will not able to find it and will throw errors during compilation
</ControlTemplate>
</cv:TemplatedTaskLoader.ResultControlTemplate>
<cv:TemplatedTaskLoader.ErrorControlTemplate>
<ControlTemplate>
...
</ControlTemplate>
</cv:TemplatedTaskLoader.ErrorControlTemplate>
<cv:TemplatedTaskLoader.LoadingControlTemplate>
<ControlTemplate>
...
</ControlTemplate>
</cv:TemplatedTaskLoader.LoadingControlTemplate>
</cv:TemplatedTaskLoader>
Hi,
I'm trying to use x:Bind
in a MAUI application (android & ios), but I can't figure out why I'm getting an error when building this code with a simple command binding.
Any idea?
Thanks
XamlC error XFC0000: Cannot resolve type "http://schemas.microsoft.com/winfx/2009/xaml:Bind"
<Button
x:Class="MauiAppTestCompiledBindings.MyButton"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiAppTestCompiledBindings"
x:DataType="local:MainViewModel"
Command="{x:Bind ClickCommand}"
Text="Click me" />
Does this works with compiledbindings ?
// ViewModel
public string ErrorOf [string index]
{
// get and set accessors
}
// XAML
< textblock Text={x:Bind ViewModel.ErrorOf ["Username"]}
if yes, please considere to add binding to arrays in readme, if no please considere open an issue
UWP Bind supports bind to array property
Hi, on may MAUI project when I set Datatype x:Bind still thinks datacontext is the base class. How to fix this , thank you.
Are there any considerations about Hot Reload? At least WPF.
Hi, my converter is declared inside merged dictionary in app.xaml. So it is accessible globaly from every page.
Whe I try to use it with x:Bind I get:
<myControls:MyEntry
x:Name="Diaria"
Title="DIARIA"
Grid.Row="7"
Keyboard="Numeric"
ReturnType="Done"
Text="{x:Bind Path=Loader.Result.Diaria, Mode=TwoWay, Converter={StaticResource DoubleToStringConverter}}" />
System.Collections.Generic.KeyNotFoundException: 'The resource 'DoubleToStringConverter' is not present in the dictionary.'
till I don't add it directly to the page.
<ContentPage.Resources>
<converters:DoubleToStringConverter x:Key="DoubleToStringConverter"/>
</ContentPage.Resources>
With normal Binding all works fine. MAUI .NET 7
I'm using this lib over the app and noticed if I do complex binding to the code generated property of CommunityToolkit.Mvvm package ObservablePropertyAttribute, and the property was not set, then I get null reference exception
Example
[ObservableProperty] private UserObservableModel _profile;
and do this in xaml
<Image Source="{x:Bind Profile.ImageUrl, TargetNullValue=images:Images.ImagePlaceholder}" />
F.e. if I have only string property to the image this works ok
[ObservableProperty] private string _imageUrl;
and do this in xaml
<Image Source="{x:Bind ImageUrl, TargetNullValue=images:Images.ImagePlaceholder}" />
Default {Binding Profile.ImageUrl, TargetNullValue=images:Images.ImagePlaceholder} works perfect
add instalation instructions, packages information etc to readme
Hello,
I'm trying to use an extension method, but I'm unable to pass more than one paramater.
Does not compile:
<Image mx:DataType="{x:Null}" m:SetImage="{x:Bind 'http://url1.com', 44}" />
public static void SetImage(this Image img, string url, int intParam)
{
intParam = // do something with it
img = CreateImage();
}
Compiles and runs as expected:
<Image mx:DataType="{x:Null}" m:SetImage="{x:Bind 'http://url1.com'}" />
public static void SetImage(this Image img, string url)
{
img = CreateImage();
}
Update:
Well, it works if I move all the required parameters inside a class and change the signature accordingly:
<Image mx:DataType="{x:Null}" m:SetImage="{x:Bind new local:ImageParameters(http://url1.com, 5)}" />
Basically, it's the same problem I reported in my first thread. It seems to me an hackish solution. It would be amazing if we could just call extensions methods from wherever they come without any additional dependent code. Would it be possible to implement multi-parameter support?
I cloned the project to get at least a partial idea on how things work and I saw that in XamlDocParser.cs
it doesn't do any processing when m.Parameters.Count > 2
. I removed the limitation just to see until at what point I could go (until here everything seemed good and all my parameters correctly detected) and to see if at least I could get something partially working, but I had to abort in the extraction process. Did you put such limitation for particular reasons?
Update 2
The more I learn the more I'm surprised from the capabilities of this library. If I change the extension method above to return a value I can do something like that:
<Image Name="ImgName" mx:DataType="{x:Null}" m:SampleProperty="{x:Bind local:Extensions.SetImage(this.ImgName, 1, true, 'and all the parameters I want')}" />
Unfortunately I didn't found a way to make this technique work with the above extension method and the only solution is still moving all parameter inside a class.
Sorry for being already at my third issue, but this library is real gold. It's the first tool that every wpf developer should have in their arsenal and I hope to create interest from users. While debugging your code I clearly saw how much efforts you put into this along with your skils! I don't know how much guys can do something like that!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.