I have a set of groups of different types of item, all inheriting form a common base type (ItemBase). Each of my groups has an Items collection of type ObservableCollection<ItemBase>.
In my SemanticZoom.ZoomedInView, I can set a DataTemplateSelector, and in SelectTemplateCore() I can cast the item parameter to detrmine which template to apply.
In my zoomed out view, though, the objects are passed around as DependencyObjects, and I can't for the life of me figure out how I can take the data passsed in to determine which template to use.
To set the items source of the GridView in the zoomed out view, I use
(semZm.ZoomedOutView as ListViewBase).ItemsSource = this.groupedItemsViewSource.View.CollectionGroups;
as this appears to be the only way to get the zoomedin and zoomedout views to synchronise (when you click on a group in the zoomed out view it should take me to the appropriate place in the zoomedinview to see that group's detail.
So, am I missing something obvious in terms of getting the actual group in SelectTemplateCore(), or failing that is there a better way of binding my ItemsSource of the ZoomedOutView?
For the appropriate way to handle casting of the DependencyObject to a usable type, see the answer to This question.
Essentially, cast it to ICollectionViewGroup to access the members.
Related
There seem to be dozens of questions about binding a NSPopupButton, so I feel a little better about struggling so much with this, but none of them seem to fix my issue.
I have an NSManagedObject subclass that has a one to many relationship with another class. Let's say Foo has a relationship to Bar, so Foo has a property that is an NSSet of Bars.
I have created an NSArrayController and bound its contentSet to the Foo object and the 'bars' key path.
I then bind my NSPopupButton's content to the array controller's arrangedObjects and its contentValues to the array controller's arrangedObject (controller key) and 'name' (the property on Bar that I want to display).
This all works fine so far, but when I try to bind the NSPopupButton's selected object to the array controller's selection The NSPopupButton displays "<_NSArrayControllerObjectProxy". I also tried adding 'name' as the keyPath for this binding, and this does make the NSPopupButton display the name correctly, but then when I change the selection in the popup the app thrown an exception:
Unacceptable type of value for attribute: property = "name"; desired type = NSString; given type = Bar;
I guess this makes sense, as the popup is trying to set the string value of 'name' as the selected Bar. I would think I would therefore need to bind a selected object and a selected value, but the XIB will disable selected value if I have a selected object set.
I have also tried binding the selected value instead, and this half works (the array controller's selection does change) but the options in the popupmenu don't change to show the one that was deselected and hide the newly selected one).
Failing all of this I read an article here: http://blog.chrisblunt.com/cocoa-bindings-and-nspopupbutton/ that says NSPopupButton "NSPopUpButton does not record the user’s selection" and to instead store your selection somewhere other than the array controller. I tried putting a currentBar property in my window and binding the selection to that instead, and although I can see that currentBar is changing (because I have another view bound to it also) the label in the popup button does not change.
If anyone can help me out I'd be very appreciative.
The FooBar thing confuses me so here is my example based on real world objects.
ExpenseTransaction has attributes (date, trxDescription, category, amount).
Category has a single attribute (name)
ExpenseTransaction.category is a To-One relationship to Category (in other words a transaction can belong to only one Category).
Category.transactions is a To-Many relationship to ExpenseTransaction (in other words many transactions can belong to the same Category).
The UI for creating a new transaction or editing and existing one uses NSPopupButton to display the list of available Categories using the name attribute. For existing transactions the popup will display the selected transactions category.
Bindings for the Category popup are as follows:
Content (Category.arrangedObjects)
Content Objects (Category.arrangedObjects) - we want to link to the actual category not its name because the attribute is a relationship not a string value
Content Values (Category.arrangedObjects.name) - we want the name to be displayed in the popup list
Selected Object (ExpenseTransaction.selection.category)
Using your FooBar analogy:
Category has a relationship to ExpenseTransaction, so Category has a property (transactions) that is a NSSet of ExpenseTransactions. Now this is pretty much the inverse of my arrangement so I don't really know how or why you would populate the popup with ExpenseTransaction objects because only one selected item in the popup could be related to the Category object when in fact you need the whole set to be related. However the other way around works just fine because the popup would contain a list of all the Foo items and so whenever you select a Bar item the corresponding Foo item could be selected from the popup.
Hope this makes sense.
The usual use for a combo box is to let it display options to the user, and then you get an OBJECT out of it. In Win32, you do it by using the CB_SETITEMDATA and CB_GETITEMDATA messages, casting between int and object pointers. In XAML, you set up a data template and the item in the list IS the object.
What is the Correct way to get this effect with a GtkComboBox?
GtkComboBox normally uses a GtkListStore as the underlaying model.
You need to create one with an extra column for the object you want to store and as you insert new items in the combo's model you also need to provide the object you want to associate with that row/item.
I'm using Mathematica and have a set of variables (A,B,C,D,...) with properties A=(blue, big, rounded), B=(red, small, spiky), and so forth. Those properties can be common between variables. What would be the best, general way to find all variables that share a common property (of being, for instance, small)? Thanks.
Here's a list of possible properties:
In[1]:= properties={"red","green","blue","big","small","rounded","spiky"};
And here's a list of objects with some of those properties
In[2]:= list={{"blue","big","rounded"},{"red","small","spiky"},
{"red","big","rounded"},{"blue","small","spiky"}};
You can find all objects that have the property of, e.g., being "blue" using Select
In[3]:= Select[list, MemberQ[#,"blue"]&]
Out[3]= {{blue,big,rounded},{blue,small,spiky}}
This could be wrapped up into a function. Although how I would write that function would depend on the data structures and usage that you're planning.
Actually, I just reread you question you have a list of objects with some properties and you want to refer to those objects by name. So you probably want something more like
In[1]:= listProperties["A"]:={"blue","big","rounded"}
listProperties["B"]:={"red","small","spiky"}
listProperties["C"]:={"red","big","rounded"}
listProperties["D"]:={"blue","small","spiky"}
Above I defined some properties that are associated with certain strings. You don't have to use strings in the above or below, and you can create a better structure than that if you want. You could also make a constructor to create the above, such a constructor could also check if the list of properties supplied is of the right form - i.e. does not have contradictory properties, are all in a list of known properties etc...
We then define a function to test if an object/string has a certain property associated with it
In[2]:= hasProperty[obj_, property_]:=MemberQ[listProperties[obj],property]
You might want to return an error or warning message if listProperties[obj] does not have a definition/rule associated with it.
Use Select to find all "objects" in a list that have the associated property "blue":
In[3]:= Select[{"A","B","C","D"}, hasProperty[#,"blue"]&]
Out[3]= {A,D}
There are other ways (probably better ways) to set up such a data structure. But this is one of the simplest ways in Mathematica.
Please could you give me an advice. I am using QSqlTableModel class to access the database table and QTableView to view it. What signal of what instance should I handle to know about user move the cursor in QTableView?
I want to update the content of TableView B after the cursor moved in QTableView A (Table B have foreign keys to table A in database)
May be somewhat from this http://doc.trolltech.com/latest/qabstractitemmodel.html?
Thanks.
Ivan, if you are talking about table cursor, you can reimplement QAbstractItemView::moveCursor method which is virtual.
If you're talking about mouse cursor, you can use QAbstractItemView::viewportEvent method to detect mouse move event. You need to set QWidget::setMouseTracking(true) to the viewport of your QTableView.
Hope that helps
Another way is using the selection model
Using a selection model
The standard
view classes provide default selection
models that can be used in most
applications. A selection model
belonging to one view can be obtained
using the view's selectionModel()
function, and shared between many
views with setSelectionModel(), so the
construction of new selection models
is generally not required.
If you have an shared selection model the views will be updated not matter which one changes. You can then react to it. The selection flags control if you want a cell, row or multiple selections.
See also working with selections :
//selection changes shall trigger a slot
QItemSelectionModel *selectionModel= treeView->selectionModel();
connect(selectionModel, SIGNAL(selectionChanged (const QItemSelection &, const QItemSelection &)),
this, SLOT(selectionChangedSlot(const QItemSelection &, const QItemSelection &)));
}
I am using a TreeView with a ListStore as model. When the user clicks on a row I want to take some action but not using the values in the cells, but using the data I created the row from...
Currently I have the TreeView, the TreeModel (ListStore) and my own data (which I ironically call model)..
So the Questions are:
Is it "right" to have a model - an object representation of the data I want to display and fill a ListStore with that data to display in a TreeView, or would it be better to implement an own version of TreeModel (wrapping my data-model) to display the data?
And also:
If someone double-clicks in a row I can get the RowActivated event (using C#/Gtk#) which provides a Path to the activated row. With that I can get a TreeIter and using that I can get the value of a cell. But what is the best practice to find the data object from which the row was constructed in the first place?\
(Somehow this question got me to the first one - by thinking would getting the data object more easy if I tried to implement my own TreeModel...)
It's quite awkward/difficult to implement TreeModel, so most people simply synch the data from their "real" model into a TreeStore or ListStore.
The columns in the store do not have to match the columns in the view in any way. For example, you can have a column that contains your real managed data objects.
When you add a cellrenderer to a TreeView (visual) column, you can add mappings between its properties and the columns of the store. For example, you could map one store column to the font of a text cellrenderer, and another store column to the text property of the same cellrenderer. Each time the cellrenderer is used to render a particular cell, the mappings will be used to retrieve the values from the store and apply them to the properties of the renderer before it renders.
Here's an example of a mapping:
treeView.AppendColumn ("Title", renderer, "text", 0, "editable", 4);
This maps store column 0 to the renderer's text GTK property and maps store column 4 to the editable property. For GTK property names you can check the GTK docs. Note that the example above uses a convenience method that adds a column, adds a renderer to it and add an arbitrary number of mapping via params. To add mappings directly to a column, for example a column with multiple renderers, pack the renderers into the column then use TreeViewColumn.AddAttribute or TreeViewColumn.SetAttributes.
You can also set up a custom data function that will be used instead of mappings. This allows you to set the properties of the renderer directly, given a TreeIter and the store - so, if all the data you want to display is trivially derived from your real data objects, you could even have your store only contain a single column of these objects, and use data funcs for all the view columns.
Here's an example of a data func that does exactly what the mapping example above does:
treeColumn.SetCellDataFunc (renderer, delegate (TreeViewColumn col,
CellRenderer cell, TreeModel model, TreeIter iter)
{
var textCell = (CellRendererText) cell;
textCell.Text = (string) model.GetValue (iter, 0);
textCell.Editable = (bool) model.GetValue (iter, 4);
});
Obviously data functions are much more powerful because they enable you not only to use properties of more complex GTK objects, but also to implement more complex display logic - for example, lazily processing derived values only when the cell is actually rendered.