MVVMCross ValueConverter Parameter - mvvmcross

Hello MVVMCross community,
My question is about ValueConverters parameters:
Is there any way to pass a variable to a Value Converter rather than a constant value as a ConverterParameter?
Something like:
<EditText
android:id="#+id/editPrice"
...
local:MvxBind="Text Price; Enabled IsPriceEnabled; BackgroundColor IsPriceEnabled, Converter=Enabled2MvxColor, ConverterParameter=Price"/>
or even pass the whole object for example:
<EditText
android:id="#+id/editPrice"
...
local:MvxBind="Text Price; Enabled IsPriceEnabled; BackgroundColor IsPriceEnabled, Converter=Enabled2MvxColor, ConverterParameter=editPrice"/>
TIA,

When using Windows/XAML IValueConverter you can't really pass data-bound entries into the value converter parameter.
However, using the Tibet binding extensions within MvvmCross, you should be able to do this if you use the form:
local:MvxBind="BackgroundColor Enabled2MvxColor(IsPriceEnabled, Price)"
For more on this - and on whole object binding, see https://github.com/MvvmCross/MvvmCross/wiki/Databinding

I had to do something similar couple of days ago: it's rather convoluted:
<controls:OptionItemControl
ItemTitle="{Binding Path=AccountSettings, Converter={StaticResource ContentItemConverter}, Mode=OneTime,
ConverterParameter=DataRoaming.Text}"
ItemInfo="{Binding Path=AccountSettings, Converter={StaticResource ContentItemConverter}, Mode=OneTime,
ConverterParameter=DataRoaming.Info}"
ItemValue="{Binding AccountSettings.DataRoaming, Mode=TwoWay}"
/>
So my ViewModel has a property AccountSettings, which is a class that has another property DataRoaming, which has several properties like .Text, .Info
I am sure there is much easier way to do what I needed it to do, but I wanted to get from using magic string; I didn't get it at the end, but at-least this makes it easier for me to read and figure out.
so in converter I get the parameter, split it; then from value type and I can navigate through the properties and get the actual value from the class. Of course I could have as well called a method.
Hope this might give you some ideas.

Related

How to prevent old data in Model from being passed into the input fields automatically?

Is it possible to prevent the data from being automatically passed to the input fields. For example - if I have an edit page where I want to change the data and I want the user to type the data again without giving him the pre-filled old data. I was looking over some documentation about the ModelState and the asp-for tag but I just couldn't find the answer.
I was looking for help and I found this post here. Well I want to do exactly the opposite.
asp-for tag helper functionality_
EDIT:
I tried to change the value attribute of the input field to empty string and it worked, however I still would like to know if there is an asp.net approach.
If you don't want to pass data from action to Edit view,you can return a view with an empty model like this:
public IActionResult Edit()
{
return View(new YourModel());
}
Or you can try to use id and name attribute to replace asp-for,so that the data will not be binded to inputs.Here is a demo.
Change
<input asp-for="TestProperty" />
to
<input id="TestProperty" name="TestProperty" />

Add components based on string variables in Blazor

We're creating a dynamic page of components in Blazor. The intention is to have dynamic applets displayed on a page. The idea is that we have a list of strings which correspond to Component names. We read through the string list and for each one, instantiate a blazor component or render fragment. These are just simple components, no passed in parameters or the like. ie:
string[] componentsStrings = {"Component1", "Component2"};
Expected output:
<Component1 />
<Component2 />
We can't come up with a way to do this. It seems like a fairly standard thing to do, but perhaps not? Does anyone know if this is even possible?
You will have to programmatically create a component which adds your custom components on the page using RenderTreeBuilder.
Chris Sainty has a blog post on this which you can read here: https://chrissainty.com/building-components-via-rendertreebuilder/
Basically there is an override for BuildRenderTree in the ComponentBase class which can be used:
public class Menu : ComponentBase
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
base.BuildRenderTree(builder);
builder.OpenElement(0, "nav");
builder.AddAttribute(1, "class", "menu");
}
}
Here is another tutorial.
Some tips from here:
Place base.BuildRenderTree(builder); at the start of the
BuildRenderTree method , not at the end.
Always start with the value 0 for the sequence parameter.

How can I customize the filter function for SelectOneMenu

I tried to find on Primefaces Documentation but I have not found how can I customize the filter function for SelectOneMenu.
I add filterMatchMode="custom" filterFunction="#{mainRandevuBean.ilFilter()}"
But I don't know how can I write bean filterFunction.
The filter is a javascript (client-side) function. It all IS in the PrimeFaces documentation, which you should always look into first, carefully, thouroughly.
So use filterFunction="myFilter"
and create a javascript function like
function myFilter(itemLabel, filterValue) {
// return true if this label matches, false otherwise
}
Just as a sidenote: primefaces documentation doesn't say anything semantically about the parameters. It also does not mention where the label comes from (in fact, the docs mention "the item value" which is not very clear).
In fact I used the JavaScript function to debug this in order to figure out what was provided by default as a label.
function filterList(label, filter){
alert("label="+label+" and filter="+filter);
return false;
}
At first I thought it would be anything like the text inside the HTML generated for each list item. But when debugging it I saw the alert said that the label was something like my.package.SomeValueObject#123456 (which is obvously the Java object toString on each item in the list).
You need to define the itemLabel property on the selectItems which is inside the selectManyMenu to generate a proper text value used by the standard filtering mechanisme. As far as I could figure out that is the only reason why you have to put itemLabel there. In the documentation itemLabel is specified before explaining filtering which is confusing.
And as far as I know the itemValue defaults anyhow to just the object value, so I believe following from the documentation is redundant.
itemValue="#{player}"
Hope it helps anyone :.)
I resolve this problem with autocomplete component. Primefaces autocomplete component with dropdown="true" property works like one menu.

Iterate through DataContext items without casting it to a viewmodel type

Is their a way to access Items contained in a DataContext without having to explicitly cast it to this ViewModel.
Let's say I'm binding a DataContext on an MvxFrameControl view, then I obtain this DataContext in code-behind once it is binded. It will look like an anonymous object containing a list of Items that are known as the children of this ViewModel. Can I swiss-bind these items, or some properties of this DataContext to another object, and so on?
I.e.
this.DelayBind(() =>
{
var data = DataContext;
// It looks like data contains something called "Items" with a list of children viewModels.
});
Can I access DataContext.Items[0], or at least DataContext.Items, and bind it to an observable collection? Then finally swiss-bind some Items to views (MvxFrameControls) on their DataContext?
So, summary: I'm curious if there is a way to work in code-behind with DataContext and its content so I could create a generic MvxFrameControl that would dispatch the data to custom views based on swiss-binding.
I have ViewModels containing lists of lists, and I want to handle a lot of situations in code-behind as I've experienced a lot of memory problems with MvxListViews containing MvxListViews.
[Edit]
This is actually what I was doing in my code that led me to think I should completely redefine how bindings are done. I'll write a minimal fake axml:
// Warning to anyone: this is a fake layout, don't use that
view_myactivity_layout.axml :
<LinearLayout>
<MvxListView
android:MvxItemTemplate="#layout/food_category_item"
local:MvxBind="ItemsSource FoodCategories" />
</LinearLayout>
food_category_item.axml:
<LinearLayout>
<TextView
local:MvxBind="Text Category" />
<MvxListView
android:MvxItemTemplate="#layout/list_of_food_for_a_category_item"
local:MvxBind="ItemsSource FoodList" />
</LinearLayout>
list_of_food_for_a_category_item.axml:
<LinearLayout>
<TextView
local:MvxBind="Text NameOfThatFood" />
<MvxListView
android:MvxItemTemplate="#layout/list_of_colors_for_that_food_item"
local:MvxBind="ItemsSource FoodList" />
</LinearLayout>
[Etc...]
Nesting binded controls works well, but there are tons of GC happening when scrolling. So that's why I was thinking about making my own binding pattern using reflection for this case.

AS3 Object indexing causing Flixel misbehaviour--what's wrong with this code?

I'm getting my feet wet with AS3, Flixel and component/entity systems (yes, all at the same time), and my entities (which subclass FlxSprite) aren't being added correctly (i.e., not at all). I've just spent a good two hours nailing down the offending line. If I remove it, the rest of the game chugs along happily.
What's wrong with this code?
public function addComponent(c:Component):void
{
var type:String = Object(c).constructor.toString();
FlxG.log("type=" + type);
this._components[type] = c; // The evil line
FlxG.log("now type=" + _components[type]);
c.setData(this);
}
components is an Object field being used as a map/dictionary. type gets set to [class PlayerComponent]. Based on googling, this is valid and should work as intended.
Based on the output from the console, it's just bailing after that line--not crashing entirely. What's going on? More details gladly offered upon request.
I'm not certain about Component - not my forte - but I do know that FlxGroup and its children (which include FlxState) have a method called add() which adds children to them.
So if you have an FlxSprite, the correct way (in flixel) to add it to the chain of things to update/draw is to use that; you can add it directly to your state or to a group that is a child of the state.
Function docs: http://flixel.org/docs/org/flixel/FlxGroup.html#add()