I'm defining a DataTemplate in code and I want to set the binding to itself.
DataTemplate = new DataTemplate(typeof(MyCustomViewCell));
DataTemplate.SetBinding(MyCustomViewCell.MyCustomProperty, "");
The code above doesn't work. You can't use an empty path in that method. The XAML equivalent I usually use is MyCustomProperty="{Binding}". This sets the property to the current BindingContext / DataContext.
What is the syntax to achieve this in C#?
Use a "." as the binding path to refer to the BindingContext itself.
DataTemplate.SetBinding<YourType>(MyCustomViewCell.MyCustomProperty, x => x.PropertyOfYourType);
Related
I'm writing a JFace dialog, and I'd like to use databing to a model object.
Looking at code I can see that there are times when I find a PojoProperties used to build the binding, while other time it is used a PojoObservables.
Looking at the Javadoc I can read:
PojoObservables: A factory for creating observable objects for POJOs (plain old java objects) that conform to idea of an object with getters and setters but does not provide property change events on change.
PojoProperties: A factory for creating properties for POJOs (plain old Java objects) that conform to idea of an object with getters and setters but does not provide property change events on change.
The same question applies to the difference that exists between BeansObservables and BeansProperties
The (obvious) difference sems to be that the observable allows to observe objects and the properties allows to observe properties, but since a Pojo has a getter and a setter for its data, what is the difference between them? And which of them should I choose for my dialog?
Here follows a code excerpt:
The POJO:
public class DataObject {
private String m_value;
public String getValue() {
return m_value;
}
public void setValue(String i_value) {
m_value = i_value;
}
}
The DIALOG (relevant part):
#Override
protected Control createDialogArea(Composite parent) {
Composite container = (Composite) super.createDialogArea(parent);
m_combo = new Combo(container, SWT.BORDER);
m_comboViewer = new ComboViewer(container, SWT.NONE);
}
The BINDING (relevant part):
// using PojoObservable
IObservableValue observeValue = PojoObservables.observeValue(m_dataObject, "value");
IObservableValue observeWidget = SWTObservables.observeSelection(m_combo);
// using PojoProperties
IObservableValue observeValue = PojoProperties.value("value").observe(m_dataObject);
IObservableValue observeWidget = ViewerProperties.singleSelection().observe(m_comboViewer);
I understand that one time I'm using a combo and another I'm using a ComboViewer, but I can get the combo from the viewer and bind the other way if I need...
Also, can I mix the two, for example use the observeValue with the ViewerProperties?
IObservableValue observeValue = PojoObservables.observeValue(m_dataObject, "value");
IObservableValue observeWidget = ViewerProperties.singleSelection().observe(m_comboViewer);
I am playing around a little with JFace viewers (especially ComboViewer) & databinding and discovered that if I use
SWTObservables.observeSelection(comboViewer.getCombo());
then databinding is not working correctly.
However, if I use
ViewersObservables.observeSingleSelection(comboViewer);
Then everything is working as expected.
Maybe this is a special for my case, so to get it a better overview I'll describe my set up in following paragraph.
I have modelObject with field named selectedEntity and entities and bind this ComboViewer to the modelObject.
I want to display all "entities" in model object, if I add any entity to the modelObject.entities collection then I want to this entity be added to combo automatically.
If user selects some item in combo I want to modelObject.selectedEntity be set automatically.
If I set modelObject.selectedEntity I want to combo selection be set automatically.
Source code can be found at: https://gist.github.com/3938502
Since Eclipse Mars, PojoObservables is deprecated in favor of PojoProperties and BeansObservables is deprecated in favor of BeanProperties so the answer to which one should be used has now become evident.
I'm coding a generic <s:GridItemEditor> for spark DataGrid, to create dynamically an appropiate UIComponent for edition, depending on properties types.
Some properties linked to GridColumn's are complex, like:
var gridColumn:GridColumn = new GridColumn("Category.Description");
I'm having this error with this complex properties:
ReferenceError: Error #1069: Property Category.Description not found on GOClases.Person and there is no default value.....
at spark.components.gridClasses::GridItemEditor/set data()[E:\dev\hero_private\frameworks\projects\spark\src\spark\components\gridClasses\GridItemEditor.as:176]**
This is the specific function where this error ocurrs:
public function set data(value:Object):void
{
_data = value;
if (_data && column.dataField)
{
this.value = _data[column.dataField];
}
}
Is it possible to avoid this error redefining properly the set data() function?
How can I workaround this?
Is it possible to define differents properties as label and itemEditor in spark DataGrid?
Thanks a lot.
This is how I solved: it's make more sense assign Object type properties to GridColumn's dataField var gridColumn:GridColumn = new GridColumn("Category"); and use labelFunction to evaluate dynamically complex properties, I used r1.deval.D library here to resolve it:
private function funcionEtiqueta(item:Object, column:GridColumn):String
{
D.eval(complexProperty,item).toString();
}
Maybe this would help somebody else.
Thanks.
Since I found the webpages explaning the bindable propety quite confusing,so I would like to post my question here,which is quite simple,if I declare a variable to be bindable,does that mean whenever I changed the value of this variable in another class,all appearence of this variable will be synchronized to be the same value at the same time?
Say,if boolean variable "select" is declared to be bindable in Class A and default to be false,and we have an if statement in class A like if(select).
Then in another class,we changed the value of "select" to be true,will that if(select) statement pass the test ?
Also,how about the following setter method that is defined to be bindable:
[Bindable]
public function set isShowingAvg(b:Boolean):void
{
_isShowingAvg = b;
hasChanged();
}
Does this code imply that changing the value of _isShowingAvg is also going to be broadcasted?
Thanks in advance.
Thanks for your idea.
Declaring a property as Bindable means that when you change the value, an event will get broadcasted. This event enables data binding, but it's not necessarily automatic.
If the consuming class is MXML and you use brackets, like this:
<mx:Button enabled="{selected}" />
Then the MXML compiler will generate the appropriate binding code and anytime selected changes, enabled will also get changed.
If you're using it outside MXML then you'll either subscribe to the event to detect changes or use BindingUtils.
In your example I think you need to mark the getter [Bindable] and not the setter.
example:
public static const SHOWING_AVG_CHANGED:String = "showingAvgChangedEvent";
[Bindable(event="showingAvgChangedEvent")]
public function get isShowingAvg():Boolean
{
return _isShowingAvg;
}
public function set isShowingAvg(isShowing:Boolean):void
{
_isShowingAvg = isShowing;
dispatchEvent(new Event(SHOWING_AVG_CHANGED));
}
I have a class called JDChart, and a class called JDLine. Inside JDChart there is a method called addLine() that expects 1 parameter of type JDLine. This is all good. but I want to be able to put this in XML Like this:
<JDChart>
<JDLine/>
<JDLine/>
<JDLine/>
</JDChart>
And for each JDLine nested in a JDChart in the MXML, I want the addLine() method to be called on the JDChart with the respective JDLine passed.
Does what I want to do make since? I am not sure how to set this up? I am assuming I have to use meta tags on the JDChart class somewhere to tell the compiler to do this? Does anyone know?
Thanks!!
I believe when you add things in MXML like that it will just construct them and then call addChild().
You could have JDChart override addChild(), and check the type of what's being added. If it's a JDLine you can then pass it to your addLine() method before passing it along to super.addChild().
If JDLine objects are going to be parented only by JDChart objects, use this.
In the added event handler of the JDLine class, add the following code:
public function onAdded(e:Event):void
{
var chart:JDChart = this.parent as JDChart;
if(!chart)
throw new Error("Parent is not JDChart");
chart.addLine(this);
}
I cureently have a set up like below
Public ClassA
property _classB as ClassB
End Class
Public ClassB
property _someProperty as someProperty
End Class
what I want to do is to databind object A to a gridview with one of the columns being databound to ClassB._someProperty. When I try to databind it as Classb._someProperty I get a "Field or Property not found on Selected Datasource" error
I have tried to use the objectContainerDataSource and also directly binding to the gridview with no success.
Has anyone come across this in the past?
Ordinary databinding doesn't generally allow for expressions. Under the hood the datagrid is using reflection (rather the executing code the way DataBinder.Eval does on an ASP.NET page) to find the property that you specify to bind to a column. To do what you want it would need to evaluate the binding as an expression, work out that you were looking for a parent -> child relation, and then reflect down to that level. AFAIK the inbuilt databinding on the grid is too dumb to know how to do this.
I've had the same issue recently, and my solution was to do a LINQ projection and bind that to the grid instead. Something like the following (in C# because I'm not comfortable with the LINQ syntax in VB):
IList<ClassA> listOfClassAObjects = GetMyListOfClassAObjectsFromSomewhere();
var projection = from ClassA a in listOfClassAObjects
select new { SomeProperty = a.SomeProperty,
SomeOtherProperty = a.SomeOtherProperty,
SomePropertyFromB = a.ClassB.SomeProperty };
datagrid.DataSource = projection;
datagrid.DataBind();
You'll get back a list of anonymous types containing that projection, and you can bind the appropriate column to SomePropertyFromB.
For extra encapsulation (if you do this a lot) put the projection into an extension method so you can do something like
var data = GetMyListOfClassAObjectsFromSomewhere().ProjectionForDataGrid();
datagrid.DataSource = data;
datagrid.DataBind();
I found the way to do this is to use a template field and eval (see below)
Set the datafield as property classB and then:
<asp:TemplateField HeaderText="_someProperty">
<ItemTemplate>
<%#Eval("classB._someProperty")%>
</ItemTemplate>
</asp:TemplateField>