We need Generic converter! We need X:Bind and X:Phase!
juepiezhongren opened this issue · 15 comments
Everyone loves binding, but every one hates the perf pit out of reflection.
Please provide us a generic IValueConverter!
interface IValueConverter<Tin,Tout>{
public Tin Convert(Tout value);
public Tout ConvertBack(Tin value);
}
Besides, X:Bind makes us with better binding perf, and X:Phase is also good for things like listView.
It's a shame for uwp that x:bind is not together with generic converters.
@Mike-EEE @birbilis
In the Windows Runtime, the language parameters for IValueConverter methods use strings, as opposed to using CultureInfo objects as they do in the Windows Presentation Foundation (WPF) and Microsoft Silverlight definitions of the interface.
https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.data.ivalueconverter
from that same article:
If you are coding in Visual C++ component extensions (C++/CX), remove the ConverterParameter attribute from the last TextBlock, because that particular string value is specific to Microsoft .NET string formatting. Your entire element should look like this:
<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay, Converter={StaticResource FormatConverter}}" />
means instead of
<TextBlock Text="{Binding Path=ReleaseDate, Mode=OneWay,
Converter={StaticResource FormatConverter},
ConverterParameter={0:d}}" />
also from that article:
Remarks
The targetType parameter of the Convert method uses different techniques of reporting the type system info, depending on whether you're programming with Microsoft .NET or Visual C++ component extensions (C++/CX).
- For Microsoft .NET, this parameter passes an instance of the System.Type type.
- For Visual C++ component extensions (C++/CX), this parameter passes a TypeName structure value. TypeName::Kind contains the simple string name of the type, similar to Microsoft .NET 's Type.Name. When the converter is invoked by the binding engine, the targetType value is passed by looking up the property type of the target dependency property. You might use this value in your Convert implementation for one of two reasons:
- Your converter has the expectation that it's always going to return objects of a specific type, and you want to verify that the binding that the converter is called for is using the converter correctly. If not, you might return a fallback value, or throw an exception (but see "Exceptions from converters" below).
- Your converter can return more than one type, and you want the usage to inform your converter which type it should return. For example, you could implement an object-to-object conversion and an object-to-string conversion within the same converter code.
language comes from the ConverterLanguage value of a specific binding, not system values, so you should expect that it might be an empty string.
parameter comes from the ConverterParameter value of a specific binding, and is null by default. If your converter uses parameters to modify what it returns, this usually requires some convention for validating what is passed by the binding and handled by the converter. A common convention is to pass strings that name modes for your converter that result in different return values. For example you might have "Simple" and "Verbose" modes that return different length strings that are each appropriate for display in different UI control types and layouts.
So, I have to say, forget cpp.
Just like creating a new x:bind things, we need pure generic binding and converter
@birbilis it seems that x:bind solves that problem and we neglected it.....
I don't get your reflection argument. I've never written any reflection in any value converters.
I get the value of generics in code behind. I don't really see the value in xaml.
@dotMorten , it is true that we don't ususally use reflection, but i guess that it does make effect, and the object boxing and unboxing is really a performance pit
@birbilis i just wondering if the entire dependency things could be redone to get rid of relection?
@juepiezhongren not sure if you had in mind something like the BindProperties method I had here:
http://clipflair.codeplex.com/SourceControl/latest#Client/Helpers/Utils/Source/Bindings/BindingUtils.cs
when you speak of more "generic" binding
Do you mean you want to bind by early-bound (resolved at compile time) property name and not late-bound (resolved at run-time via reflection, or lookup tables or whatever) one for example?
note that I was only interested in binding properties to properties there (like when you do wiring), not to expressions (which can do only 1-way binding obviously). Btw, speaking of two-way binding of properties, I had done loop breaking of such wirings in Java ~20 years ago (when working on E-Slate and its Plugs mechanism - http://e-slate.cti.gr) with TLS (Thread-Local Storage). Don't remember if C#/.NET support thread-local fields though in classes like Java had.
@birbilis these days, i only think early-bound be necessary. Sure, runtime-bound could benefit from things like xaml-parser etc, but considering ios forbidding jsPatch and future mono-wasm, its significance seems limited, just my opinion.
@juepiezhongren actually, I'm interested in End User Programming/Development and constructivism, esp. in educational software, so there one definitely needs late-binding since the end-user can choose to be the author, remixer etc.
Especially when you want to have multiple development modalities like we were doing back then with E-Slate, e.g. when you have both structural "programming" via wiring (we had data flow - say wire Integer to Integer, and interface - say wire Plane to Map - matching via visual plugs) and verbal expression via scripting (e.g. we had Logo and Javascript)
but to not deroute a lot from your suggestion, isn't it missing some functionality judging from the Microsoft documentation excerpts I posted above?
@birbilis i got ur idea, "UI Dev 4 Dev". That's absolutely where late-bind must implement.
Besides, for pure customers, there shall be performance one, as the reasons that ios always beats android.