JavaFX Bindings.BindContentbidirectional removes all observableList Contents? - binding

i have a problem in JavaFX Binding, I have two observable Lists one of them is static, so when i bind them using (Bindings.bindcontentbidirectional), the two lists get empty and i checked by printing their size and the console shows before binding "List 1 = 3" "List 2 = 0" and after the Bind command the two lists size is ZERO!,so what is the problem??, another question, does it matter in a bidirectional bind who comes in the first parameter???

Yes, the order of the parameters does matter. When creating the Binding, the first list will be cleared and filled with the content of the second list. After this point, they will be synchronized bidirectionally as long as the Binding exists.
Assuming you did something like Bindings.bindContentBidirectional(list1, list2), your first list has been cleared upon creating the Binding because list2 was empty at that point. So everything went as to be expected.

Related

Get child node by name in Umbraco 7.8.1

My Content structure is:
-Home (the site root node)
-About Us
-Our Sevice1
-Our Sevice2
-Our Sevice3
I created a macro for Our Services.
In macro, I want Our Sevice1, Our Sevice2, Our Sevice3...
But in the list variable About Us also come but I don't want it
I want only our service name of the child node
var list= CurrentPage.Children();
About Us also come on the list but I don't want it.
The reason that you see the About Us page in the collection is because you use the Children method.
With the Children method you ask for the direct child nodes of a parent node traversing one level down. So in this case you ask for all direct children of the home page so this works like expected.
What you are trying to achieve is a collection of of all Service nodes. To accomplish this you could do something like this.
Make sure that you have a seperated Document Type for your service nodes ( like for example doc type Service Page ).
Then you can do the following:
var servicePages = CurrentPage.ServicePages;
You can view the docs about it here:
https://our.umbraco.org/documentation/reference/querying/dynamicpublishedcontent/collections
But all of this is using dynamic syntax, this will be removed in future versions of Umbraco. So I suggest you go and use the strongly type syntax.
Then this can be changed by:
var servicePages = Model.Content.Children.Where(x => x.DocmentTypeAlias == "servicePage");
What this does is take the IPublishedContent object of the current page you are on, which is the Home Page then you take all children which has a document type alias of type servicePage.
Like #Mivaweb mentioned, it's better to not use dynamics (I think for performance in addition to being removed in the future).
However, I don't think you have to create a separate doc type, although that will work too. The predicate for the Where method should handle other expressions such as:
var servicePages = Model.Content.Children.Where(x => x.Name.StartsWith("Our Sevice"));

MapItemsControl does not reflect removing of corresponding ItemsSource

Within a UWP-App (Windows 10) I've got a MapControl and I'm using MapItemsControl to deliver an overlay for that map. The ItemsSource of that MapItemsControl (which is an ObservableCollection) is bound via xaml, but is only working in one direction:
Adding items to that collection is working fine and those items are shown in that MapControl too.
Removing items to that collection is working too, but seemingly only within that collection - the visual representation on my MapControl does not react to removing elements. This can lead to infinite adding of items into that map, while no item gets ever removed.
The ObservableCollection gets updated quiet frequentely (via MapControl.ZoomLevelChanged-Event) and gets cleared & repopulated in that process - might that be a problem?
Binding via xaml looks like this:
<maps:MapControl
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
[...]>
<maps:MapItemsControl ItemsSource="{x:Bind Path=MapDirectionOverlay, Mode=OneWay}"/>
</maps:MapControl>
Any suggestions?
Removing items to that collection is working too, but seemingly only within that collection- the visual representation on my MapControl does not react to removing elements.
ObservableCollection represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. So if you add or remove items, the collection and ItemsSouce of binding should be reflect updated.
Since I don't know how you removing the item, by using remove methods of ObeservableCollection such as Remove,RemoveAt and RemoveItem, they should work well with removing items as well as removing correspondent item in the map.
But if you just set the ObeservableCollection to null will take no effect on the ItemsSouce.In this scenario you need to set the ItemsSouce of MapItemsControl to null manually but which is not recommend.
Since using Clear-Method did not do the trick, I tried using other remove-methods of the ObservableCollection and eventually that worked.
So in the end, this is the workaround I'm using:
private new void Clear()
{
for (int i = this.Count - 1; i >= 0; i--)
{
this.RemoveAt(i);
}
}
After all I still don't get, why a simple Clear would not work, since it still should raise a NotifyCollectionChangedAction. (Correct me if I'm wrong)

Find pages with tag

In a Umbraco 7 solution, i have a Tags Content picker on all pages. Pages can with this, set tags on each page.
I then want to get alle pages, within the intire site, that has, lets say tag 111 (id, not name).
I have tried with:
var ids = Model.MacroParameters["tags"]; //the tags to show
CurrentPage.AncestorOrSelf(1).Descendants().Where(x => ids.Contains(x.tags.ToString()));
But that gives me the error:
Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type
Whats the correct way?
Solved it with;
Umbraco.Content(rootId).Descendants().Where("tags.Contains(#0)", ids);
You have a few options, depending on whether you prefer a dynamic or strongly typed view model.
Strongly Typed API
Umbraco.TypedContentAtRoot().Descendants().Where(x => x.tags.Contains(ids));
Dynamic API
Umbraco.ContentAtRoot().Descendants().Where("tags.Contains(#0)", ids);
Please note that the Contains statement may give you inconsistent results, as the tags property seems to be returning a comma separated list. In that case you can try splitting the string or install the Core Property Value Converters package and get the tags as IEnumerable<IPublishedContent>
Always try to avoid using Descendants, especially on the root node.
To get the tags for a property:
ApplicationContext.Current.Services.TagService.GetTagsForProperty(Model.Content.Id, "propertyname")
To find content with a specific tag:
ApplicationContext.Current.Services.TagService.GetTaggedContentByTag("tag")

Dynamic Tag Management - Storing

We're in the process of moving to DTM implementation. We have several variables that are being defined on page. I understand I can make these variables available in DTM through data elements. Can I simply set up a data elem
So set data elements
%prop1% = s.prop1
%prop2% = s.prop2
etc
And then under global rules set
s.prop1 = %s.prop1%
s.prop2 = %s.prop2%
etc
for every single evar, sprop, event, product so they populate whenever they are set on a particular page. Good idea or terrible idea? It seems like a pretty bulky approach which raises some alarm bells. Another option would be to write something that pushes everything to the datalayer, but that seems like essentially the same approach with a redundant step when they can be grabbed directly.
Basically I want DTM to access any and all variables that are currently being set with on-page code, and my understanding is that in order to do that they must be stored in a data element first. Does anyone have any insight into this?
I use this spec for setting up data layers: Data Layer Standard
We create data elements for each key that we use from the standard data layer. For example, page name is stored here
digitalData.page.pageInfo.pageName
We create a data element and standardize the names to this format "page.pageInfo.pageName"
Within each variable field, you access it with the %page.pageInfo.pageName% notation. Also, within javascript of rule tags, you can use this:
_satellite.getVar('page.pageInfo.pageName')
It's a bit unwieldy at times but it allows you to separate the development of the data layer and tag manager tags completely.
One thing to note, make sure your data layer is complete and loaded before you call the satellite library.
If you are moving from a legacy s_code implementation to DTM, it is a good best practice to remove all existing "on page" code (including the reference to the s_code file) and create a "data layer" that contains the data from the eVars and props on the page. Then DTM can reference the object on the page and you can create data elements that map to variables.
Here's an example of a data layer:
<script type="text/javascript">
DDO = {} // Data Layer Object Created
DDO.specVersion = "1.0";
DDO.pageData = {
"pageName":"My Page Name",
"pageSiteSection":"Home",
"pageType":"Section Front",
"pageHier":"DTM Test|Home|Section Front"
},
DDO.siteData = {
"siteCountry":"us",
"siteRegion":"unknown",
"siteLanguage":"en",
"siteFormat":"Desktop"
}
</script>
The next step would be to create data elements that directly reference the values in the object. For example, if I wanted to create a data element that mapped to the page name element in my data layer I would do the following in DTM:
Create a new data element called "pageName"
Select the type as "JS Object"
In the path field I will reference the path to the page name in my data layer example above - DDO.pageData.pageName
Save the data element
Now this data element can be referenced in any variable field within any rule by simply typing a '%'. DTM will find any existing data elements and you can select them.
I also wrote about a simple script you can add to your implementation to help with your data layer validation.Validate your DTM Data Layer with this simple script
Hope this helps.

Wix: ListBox value limitation

Value field in ListBox table has String[64] type. Is there posible to expand this 64-characters limitation? I need to store some directory pathes there.
It's probably (never tried) possible in WiX to override the default schema of he ListBox table. I know in InstallShield I just go to the direct editor and adjust it. WiX has a template schema that is used to build the MSI and you might be able to use the Table element to redefine it. Or it might just give you an error message saying you are defining a well known table.
However, I'm not sure if there would be any side effects in the ListBox control if you exceed 64 char. I don't see anything in the MSI SDK saying what's allowed so I guess your milage may vary.
Here's a trick that you might like though. It's called the evil twin dialog trick. See, in MSI there's a bug that UI elements don't refresh very well and this trick works around it. Consider this:
Dialog1 with ListBox associated to property TESTPROP and Items One value 1 and Two value 2.
Textlabel that displayes [TESTPROP].
When start the dialog the text label is empty after clicking a row in the listbox. Click back and next and suddenly it has the expected text of 1 and 2.
Now create a clone of this dialog ( Dialog2 ) and put a control event on the Listbox of dialog1 that says NewDialog Dialog2 condition=1 and put a control event on the Listbox of dialog2 that says NewDialog Dialog1 condition = 1
Now when you run it the screen refreshes ( although with a big of an ugly flicker ) See it looks like it's the same dialog only it's really the evil twin dialog that's being transitioned to so that the data refreshes correctly.
Now for extra credit use your custom actions to do something like this
ListBox Item 1 Text C:\Pro...Foo\Bob value LISTBOXDIRPROP1
ListBox Item 2 Text C:\Pro...Foo\Ed value LISTBOXDIRPROP2
Property LISTBOXDIRPROP1 = C:\Program Files\Foo\Bob
Property LISTBOXDIRPROP2 = C:\Program Files\Foo\Ed
Then set your TextLabel to display [[TESTPROP]]. This tells it to get deference the value of the value of the property. In other words, TESTPRO = LISTBOXDIRPROP1 = C:\Proggram Files\Foo\Bob
This trick would allow you to display a line that fits the 64 char constraint yet gives additional information when the user selects it.

Resources