e4 Key binding in fragment is not working - key-bindings

I would like to set up a key binding for a part that is defined in a fragment as a part descriptor. I create the part programmatically and can see the binding context in MPart#getBindingContexts
My fragment definition is as follows:
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_ywpQQJDUEeyZIrUsxxGUrA" featurename="bindingTables" parentElementId="xpath:/">
<elements xsi:type="commands:BindingTable" xmi:id="_2x0msJDUEeyZIrUsxxGUrA" elementId="de.myapp.bindingtable.0" bindingContext="_IRgUMJDWEeyZIrUsxxGUrA">
<bindings xmi:id="_bke2MJDVEeyZIrUsxxGUrA" elementId="de.myapp.keybinding.0" keySequence="M1+Z" command="_uXK5IJDVEeyZIrUsxxGUrA"/>
<bindings xmi:id="_5KGQMJDVEeyZIrUsxxGUrA" elementId="de.myapp.keybinding.1" keySequence="M1+Y" command="_w8zeoJDVEeyZIrUsxxGUrA"/>
</elements>
</fragments>
<fragments xsi:type="fragment:StringModelFragment" xmi:id="_EQShgJDWEeyZIrUsxxGUrA" featurename="rootContext" parentElementId="xpath:/">
<elements xsi:type="commands:BindingContext" xmi:id="_IRgUMJDWEeyZIrUsxxGUrA" elementId="de.myapp.bindingcontext.tabeditor" name="tabeditor"/>
</fragments>
There is a global binding context defined in the base application.e4xmi. Could this be the problem? That binding context is active in my part.

Related

How can I reference Colors.xaml in MauiProgram.cs?

My problem is that I'm referencing a static resource, primary (as a color) in my MainPage, but when I have MainPage in the constructor of App() for Dependency Injection, primary isn't defined yet because its reference is loaded from App.xaml.
public partial class App : Application
{
//MainPage gets loaded first with a reference to
//StaticResource Primary which doesn't exist yet.
//An exception is thrown in mp.InitializeComponent()
//complaining about StaticResource Primary not existing
public App(MainPage mp, MainPageViewModel vm)
{
//StaticResource Primary is defined in here
InitializeComponent();
MainPage = mp;
MainPage.BindingContext= vm;
}
}
I can work around this by doing the following:
Adding Colors (and Styles) to the ResourceDictionary of MainPage:
<ContentPage.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</ContentPage.Resources>
But then I also have to add a ResourceDictionary in Styles.xaml referencing Colors.xaml:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
This approach is fine for a small app, but I have many view pages utilizing Colors.xaml in the app I'm developing. Is there any way I can globally reference Colors.xaml and Styles.xaml in MauiProgram.cs? (So they're registered before DI takes place with MainPage)
You don't need to reference colors. What you actually ask is:
"How to resolve services with dependency injection".
You can add to any class IServiceProvider, and "ask" for a service to be provided to you. When you "ask" for your View, it will cascade (or to use your term: dominos down the line) and call the required constructors for ViewModel. And if your ViewModel uses something like ISettings, It will call the constructor of your MySettings class that implements the interface and so on.
The whole idea of using DI is to let it do this work for you.
You should not pass pages, in the constructor of you Application class. Why? Because when you construct it, LoadFromXaml is not called yet. But nothing is stopping you from having IServiceProvider in your constructor. And request services after Initialization is done.
This is good theory: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-7.0
This is good example: https://stackoverflow.com/a/32461714/6643940

issues with template binding and binding of custom component

I'm new to the world of WP7 and .net programming for that matter and i need help. I have a custom component that has a property that uses template binding.
<TextBlock Text="{TemplateBinding Info}" FontSize="20" Grid.Row="1" TextWrapping="{TemplateBinding TextWrap}"/>
I defined the dependency properties in the .cs file.
Now in my page.xaml i placed the custom component like so,
<rounded:RoundedImageView x:Name="pivotItem1" Info="Test bind" BorderBrush="White" ImageSrc="Images/default_service.png" TextWrap="Wrap"/>
Which works ok, now I want the Info and TextWrap properties to be changed dynamically based on some external variables so I did this
<rounded:RoundedImageView x:Name="pivotItem1" Info="{Binding sopInfo}" BorderBrush="White" ImageSrc="Images/default_service.png" TextWrap="{Binding wrap}"/>
where sopInfo and wrap are the external variables defined in the backing cs file of the page. But this doesn't work, the Info and TextWrap values do not change. How can i achieve it?
Thanks
Try to set the DataContext of your Page like this:
<phone:PhoneApplicationPage
DataContext="{Binding RelativeSource={RelativeSource Self}}" />
Then make sure that sopInfo and wrap are public DependancyProperties of your Page class.
public static readonly DependencyProperty sopInfoProperty =
DependencyProperty.Register(
"sopInfo", typeof(String),
);
public string sopInfo
{
get { return (string)GetValue(sopInfoProperty); }
set { SetValue(sopInfoProperty, value); }
}

Date conversion exception inside JSF composite component

When I access a JPA managed date value from JSF, it comes back with an javax.faces.component.UdateModelException saying
'Cannot convert 01.01.10 00:00 of type class java.util.Date to class org.apache.openjpa.util.java$util$Date$proxy
Using a JPA-managed date value (which means it is proxied) works fine when it is used directly from the EL likes this:
'<h:outputLabel value="MyDateValue" for="input"/>
'<h:inputText id="inputDate" value="#{bean.myDate}"/>
However, it causes trouble when trying to use it with composite components
and gives back the following converter exception and thus can't update the model...
The (simplified) JSF composite component inputDate.xhtml
<head>
<title>A date input field</title>
</head>
<composite:interface>
<composite:attribute name="dateValue"/>
</composite:interface>
<composite:implementation>
<h:outputLabel value="MyDateValue" for="input"/>
<h:inputText id="input" value="#{cc.attrs.dateValue}"/>
</composite:implementation>
Assumption:
It seems the proxy replacement in OpenJPA is handled differently when the value is being accessed from inside a composite. My guess is the EL-resolver handles calls to object values differently when it is passed to composites. Passing it to composites means it is first accessed within the composite, which is too late and the required replacement of the proxy is not accomplished (thus the converter exception)
So I tried to change the Expression Language for MyFaces, but it didn't work in Websphere, even though I changed the class loading to parent last and provided el-impl and el-api from glassfish in the lib folder and inserted the necessary context-param for MyFaces
How do you guys use JPA-managed dates (or other proxied entities) in composite components???
If you are using the sun EL implementation you might use the following ELResolver which works around this issue:
public class BugfixELResolver extends ELResolver {
//...
#Override
public Class<?> getType(ELContext anElContext, Object aBase, Object aProperty) {
if (aBase.getClass().getCanonicalName().equals("com.sun.faces.el.CompositeComponentAttributesELResolver.ExpressionEvalMap")){
Object tempProperty=((Map)aBase).get(aProperty);
if (tempProperty!=null&&tempProperty.getClass().getCanonicalName().equals("org.apache.openjpa.util.java.util.Date.proxy")) {
anElContext.setPropertyResolved(true);
return java.util.Date.class;
}
}
return null;
}
}
Add it to the faces-config this way:
<el-resolver>
xxx.BugfixELResolver
</el-resolver>
This workaround can also be used in environments where you can not change the EL implementation (like websphere etc.).
Here is the workaround. The problem seems to be WebSpheres' ExpressionLanguage Implementation or rather the order resolvers are executed. Registering the JBoss EL implementation works and resolves the date proxies before calling the composite component. I also tried the Glassfish EL, but it didn't work either...
Registering a alternative EL is quite strange: The setting in web.xml for MyFaces is
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
</context-param>
Additionally under WebContent/META-INF/services/ a file named javax.el.expressionFactory is needed with this single line org.jboss.el.ExpressionFactoryImpl. The class comes from jboss-el-2.0.2.CR1.jar
(sorry, couldn't find the link to a maven repo)
I will keep you updated once I find a better solution...

Setting layout properties in code at runtime

I am having trouble finding out how to set layout properties in my code.
My controls are being generated at runtime so I can't set the layout in my xml.
I would like to be able to set properties such as
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_weight="1"
However I can't find any documentation or examples on how to do this in code.
Is it possible with the current version of Mono for Android?
Relevant thread on the Mono for Android mailing list.
Many of the constructors take an IAttributeSet instance, so (worst case) you could always provide the XML custom attributes through that parameter when invoking the e.g. RelativeLayout(Context, IAttributeSet) constructor.
Resource attributes are handled specifically in Java code, and thus can potentially vary from one class to another. For example, the RelativeLayout constructor implementation.
Because of this, attributes can (and will be) specific to a given type. For example, as best as I can tell from quickly perusing the Android source, it's not valid for a type to have both android:layout_alignParentBottom and android:layout_weight attributes, as android:layout_alignParentBottom appears to be specific to the RelativeLayout type, while android:layout_weight is specific to LinearLayout, and there is no inheritance relationship between RelativeLayout and LinearLayout.
That said, to programmatically assign the android:layout_alignParentBottom property, it looks like you'd want to do:
// Get a RelativeLayout.LayoutParams instance
// Option 1, if you have an existing RelativeLayout instance already:
var p = (RelativeLayout.LayoutParams) layout.LayoutParameters;
// Option 2: if you don't.
var p = new RelativeLayout.LayoutParams (context, null);
// Enable layout_alignParentBottom:
p.AddRule ((int) LayoutRules.AlignParentBottom);
This uses the RelativeLayout.LayoutParams.AddRule method to enable the layout option. The int cast is necessary because we didn't realize that AddRule() should take a LayoutRules enum; oops.
To programmatically assign the android:layout_alignParentRight property:
p.AddRule ((int) LayoutRules.AlignParentRight);
As noted above, it appears that android:layout_weight is specific to LinearLayout, so we can't use RelativeLayout.LayoutParams to set this. Instead, we need to use LinearLayout.LayoutParams to set the LinearLayout.LayoutParams.Weight property:
// Just like before, but get a LinearLayout.LayoutParams instance
// Option 1, if you have an existing LinearLayout instance already:
var p = (LinearLayout.LayoutParams) layout.LayoutParameters;
// Option 2: if you don't.
var p = new LinearLayout.LayoutParams (context, null);
// Enable layout_weight:
p.Weight = 1.0f;

Silverlight 3 - Creating Custom Objects inside a Merged ResourceDictionary

I have custom classes that I currently instantiate within App.xaml as resources. I want to move these custom objects into a Merged ResourceDictionary, where they are used within styles, and keep them close to where they are used.
Here's an example of what I want, arbitrarily using fake converter objects, but they could be any custom object...
App.xaml (namespace declarations ommitted):
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Merged.xaml" />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="SomeStyle" TargetType="SomeControl">
...
</Style>
...
</ResourceDictionary>
And then in Merged.xaml (namespace declarations omitted):
<ResourceDictionary>
<cvt:VisibilityToBoolConverter x:Key="BoolToVisibility" Inverted="True"/>
<cvt:VisibilityToBoolConverter x:Key="NotBoolToVisibility" Inverted="True" Not="True"/>
<Style x:Key="SomethingThatUsesVisibilityToBoolConvertersStyle" TargetType="SomeOtherControl">
....
</Style>
</ResourceDictionary>
The issue I'm seeing is this: when I create the BoolToVisibility and NotBoolToVisibility objects (as well instantiating other objects that are instances of custom classes I have created) just as part Application.Resources, they are created and all the references work as expected; however, when I move these into a Merged Resource Dictionary (as I have in the sample above), I get a malformed Application exception when the Silverlight application loads.
I belive this to be an issue with how objects are instantiated differently in Merged Resource Dictionaries (I belive it is more of a lazy-load approach), but I would expect it to work nonetheless.
I am very much able to add Style objects, DataTemplates, ControlTemplates, and the like. But when I want to create instances of custom classes that are named or keyed using Xaml, it works great inside of App.xaml's Application.Resources directly and Application.Resources/ResourceDictionary as well. As soon as they are moved into a merged dictionary, it throws the exception. Is this by design? Any other ideas that work? Thanks in advance...
I have FINALLY worked around this. I took a page out of how the App class gets instantiated and did the same with the Merged.xaml file. I created a class with "code-behind" for Merged.xaml, called Merged that inherits from ResourceDictionary. I then (borrowing from App.g.cs), I initialize the component by loading from the Merged.xaml file during construction.
Merged.xaml.cs:
public partial class Merged : ResourceDictionary
{
private bool _contentLoaded;
public Merged()
{
InitializeComponent();
}
public void InitializeComponent()
{
if (_contentLoaded)
{
return;
}
_contentLoaded = true;
System.Windows.Application.LoadComponent(this, new System.Uri("/MySilverlightApp;component/Merged.xaml", System.UriKind.Relative));
}
}
The Merged.xaml file looks exactly the same as in my original question, using ResourceDictionary as it's root element.
The App.xaml is SLIGHTLY different. Instead of referencing the Merged ResourceDictionary by using the ResourceDictionary element and the Source attribute, I simply referenced the Merged class:
<Application.Resources
xmlns:msa="clr-namespace:MySilverlightApplication">
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<msa:Merged />
</ResourceDictionary.MergedDictionaries>
<Style x:Key="SomeStyle" TargetType="SomeControl">
...
</Style>
...
</ResourceDictionary>
</Application.Resources>
Viola! It works.
You can avoid the extra codebehind by setting the build action for your shared xaml to "Resource" and reference it as /AssemblyName;component/Shared.xaml. For a reason that mostly escapes me, referencing it in this way allows custom object instantiation to work properly.

Resources