Load three UITableViews from different datasources - xcode

I have three uiTableViews on a view.
I have created three different NSMutableArray loaded with different data.
I need to place one of the NSMutableArray as the datasource for one of the UITableView.
I am able to assign all three UITableViews datasource through the viewDidLoad of the form.
But what I really need to do, is assign each of the UITableView datasource to a different NSMutableArray.
How can I perform this task?
thanks
tony

If all three UITableViews share the same datasource object (the object that holds all three of your arrays), then just use if statements to differentiate between the table views asking for the data:
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
// If table 1 is asking, give it table 1 data...
if (tableView == myTableView1)
{
// Assume all sections have 3 rows each for
// purposes of simple demonstration...
return [dataSourceForTable1 count];
}
// If table 2 is asking, give it table 2 data...
if (tableView == myTableView2)
{
// Assume all sections have 3 rows each for
// purposes of simple demonstration...
return [dataSourceForTable2 count];
}
// If table 3 is asking, give it table 3 data...
if (tableView == myTableView3)
{
// Assume all sections have 3 rows each for
// purposes of simple demonstration...
return [dataSourceForTable3 count];
}
// The compiler will complain if we don't have
// a final return since it's possible none of the
// if statements will be true ...
return 0;
}

Related

How to count total Local Data rows for Data Driven testing and then perform a function on a particular row?

I'm writing test automation scripts that is based on Data Driven testing for Web Browser test. I'm using Local Data as my data source.
Eg: Local Data table contains 2 rows and 2 columns for Username and Password.
I'm wondering is there is a way to perform a row "Count" function for the Local Data table.
And then,if the row count is two, perform a specific function.
The idea is something like this :
if LocalData.Row = 2 then
//Execute a function
else
//Close Browser
I can't seem to find any resources in the net for this. I'm just being introduced to Telerik so i'm learning as it goes and i'm really hoping you guys can help to give some pointers on this question.
Many many thanks in advance :)
Column and row are two different things.
When accessing the column by the RAD_Grid.MasterTableView.Columns.
You will be able to modify all the properties of a column. Like :
FilterDelay, CurrentFilterFunction, ShowFilterIcon, DataField, UniqueName, Display, Exportable...
foreach (GridColumn column in RAD_Grid.MasterTableView.Columns)
{
if (column is GridBoundColumn)
{
GridBoundColumn boundColumn = column as GridBoundColumn;
boundColumn.CurrentFilterValue = string.Empty;
}
}
To iterate through the row, on the data bound:
protected void Unnamed_DataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
if (e.Item is GridDataItem)
{
GridDataItem item = (GridDataItem)e.Item;
// LOGIC
}
//Total Item Count:
if (e.Item is GridPagerItem)
{
int itemsCount = ((GridPagerItem)e.Item).Paging.DataSourceCount;
}
}
Or
GridItemCollection gridRows = RAD_Grid.Items;
int i;
foreach (GridDataItem data in gridRows)
{
i++;
ItemClass obj = (ItemClass)data.DataItem;
}
As its not really clear what you want I will give you an other way around.
In your grid put a templated Column. I' am pretty sure that's what you are looking for. And if the logic is complexe put it in a function in code behind and simply :
<asp:Label ID="lbl_Exmpl" runat="server"
Text=' <%# MyFunction( Convert.ToInt32(Eval("Mydata")) ) %>' />

How to set and/or retrieve default cell padding in iText 7

When you create a table in iText 7 using the Table and Cell classes, the table cells come with some padding built in by default. As far as I can tell by looking at a generated document, it appears to be about 2 PDF units.
Is there any way I can retrieve this value for use in calculations? Also, is there any way I can change this default, so that I can set my own padding to be used in all cells in all tables, instead of having to set it individually on every cell?
Please take a look at the iText 7: Building Blocks tutorial.
In the Before we start section, we see that every building block is derived from a class named ElementPropertyContainer. This class is a container of properties.
In the case of the Cell class, there is a set of properties that define the padding. You can get these properties the generic way (using a method of the AbstractElement class) like this:
System.out.println(cell.getProperty(Property.PADDING_LEFT));
System.out.println(cell.getProperty(Property.PADDING_RIGHT));
System.out.println(cell.getProperty(Property.PADDING_TOP));
System.out.println(cell.getProperty(Property.PADDING_BOTTOM));
But why make it difficult if you can also simply use convenience methods that is available in the BlockElement class:
System.out.println(cell.getPaddingLeft());
System.out.println(cell.getPaddingRight());
System.out.println(cell.getPaddingTop());
System.out.println(cell.getPaddingBottom());
As you can see in the tutorial, the Cell class is a subclass of the BlockElement class. The BlockElement is a subclass of the AbstractElement class. The AbstractElement class is a subclass of the ElementPropertyContainer class.
If you want to change the padding (or the margin if you are so inclined), please read chapter 5 of that tutorial. It has an example, named CellMarginPadding:
public void createPdf(String dest) throws IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
Table table = new Table(new float[]{2, 1, 1});
table.setBackgroundColor(Color.ORANGE);
table.setWidthPercent(80);
table.setHorizontalAlignment(HorizontalAlignment.CENTER);
table.addCell(
new Cell(1, 3).add("Cell with colspan 3")
.setPadding(10).setMargin(5).setBackgroundColor(Color.GREEN));
table.addCell(new Cell(2, 1).add("Cell with rowspan 2")
.setMarginTop(5).setMarginBottom(5).setPaddingLeft(30)
.setFontColor(Color.WHITE).setBackgroundColor(Color.BLUE));
table.addCell(new Cell().add("row 1; cell 1")
.setFontColor(Color.WHITE).setBackgroundColor(Color.RED));
table.addCell(new Cell().add("row 1; cell 2"));
table.addCell(new Cell().add("row 2; cell 1").setMargin(10)
.setFontColor(Color.WHITE).setBackgroundColor(Color.RED));
table.addCell(new Cell().add("row 2; cell 2").setPadding(10)
.setFontColor(Color.WHITE).setBackgroundColor(Color.RED));
document.add(table);
document.close();
}
This is what it looks like:
I'm sorry if it hurts the eyes a bit, but using those colors seemed like the best way to explain the difference between the margin and the padding to me.
Most of the properties are inherited. For instance: if you set the font for a Div, that font will be the default font for all the elements added to that Div. There are some exceptions though. The padding is one of them. This is how the default values for the properties specific to the Cell class were defined:
#Override
public <T1> T1 getDefaultProperty(int property) {
switch (property) {
case Property.BORDER:
return (T1) (Object) DEFAULT_BORDER;
case Property.PADDING_BOTTOM:
case Property.PADDING_LEFT:
case Property.PADDING_RIGHT:
case Property.PADDING_TOP:
return (T1) (Object) 2f;
default:
return super.<T1>getDefaultProperty(property);
}
}
As you can see, there is no padding value for the complete cell; the padding consists of four values that incidentally are identical by default.
If you don't like to define a padding different from the default for each Cell, just create a subclass of Cell and call it MyCustomCell. Make it custom in the sense that it uses the padding of your choice by overriding the getDefaultProperty() class.
In the tutorial, you'll find an example of a subclass that draws cells with borders that have rounded corners so that we don't have to set declare a renderer every time we want to introduce rounder corners.
I am the original author of that documentation. I hope you find it useful to answer these and other questions about the Cell and other objects in iText 7.
I did this in C# per #Bruno Lowagie override route to set a default as no padding and no border:
public class BorderlessCell : Cell
{
public BorderlessCell(int rowSpan, int colSpan) : base(rowSpan, colSpan) { }
public BorderlessCell() : base() { }
public override T1 GetDefaultProperty<T1>(int property)
{
switch (property)
{
case Property.BORDER:
return (T1)(Object)(Border.NO_BORDER);
case Property.PADDING_BOTTOM:
case Property.PADDING_LEFT:
case Property.PADDING_RIGHT:
case Property.PADDING_TOP:
return (T1)(Object)(0);
default:
return base.GetDefaultProperty<T1>(property);
}
}
}
What works for me was editing the WidthPercentage, for example:
table.setWidthPercentage(100)

JavaFX8: Strings are not displayed in TableView

I have the following problem: I try to populate a tableview in JavaFX8 with an array. So, I try to add the array as a row to the tableview. I run this code in the Controller of my FXML file, when enter is pressed. This is the code:
String[] words = {"ace", "boom", "crew", "dog", "eon"};
List<String> tableViewRow = Arrays.asList(words);
ObservableList<String> row = FXCollections.observableList(tableViewRow); //observableArrayList also doesn't work
transactionOverview.getItems().add(row);
transactionOverview is my tableview, and the String[] is just a placeholder for my actual String[]. I tried to create my tableview in multiple ways:
public TableView<ObservableList<String>> transactionOverview;
public TableView<ObservableList> transactionOverview;
public TableView transactionOverview;
None of them works.
The problem is that tableview gets an extra row, which I can select, but there are now string values visible in the tableview. I don't know if they are added.
My code is based on Javafx 2.2 - Dynamic table view - table data (answer from Jitendra Pareek), and I have chosen for this solution because I don't want to use an extra class to populate my tableview.
Any help is appreciated!
Since (according to your comments) you have a fixed number of columns, I would strongly recommend creating a model class to hold the items in each row of the table. You can then follow the standard patterns and it should work readily.
However you manage a TableView, you must provide a cell value factory for each column. This is essentially a function that specifies how to get the value for a cell from the item in the row. If your use a model class that uses JavaFX properties, then you can use a PropertyValueFactory (though Java 8 lambda expressions make that pretty much redundant). Otherwise, you need to implement a callback.
If you really want to use a list structure to hold the data for each row, and assuming your table and table columns are all defined in the FXML file, you would do something like this in your controller class:
#FXML
private TableView<ObservableList<String>> transactionOverview ;
// ...
public void initialize() {
for (int i=0; i < transactionOverview.getColumns().size(); i++) {
TableColumn<ObservableList<String>, String> col = transactionOverview.getColumns().get(i);
final int colIndex = i ;
col.setCellValueFactory( (CellDataFeatures cellData) -> {
ObservableList<String> rowData = cellData.getValue();
return new ReadOnlyStringWrapper(rowData.get(colIndex));
});
}
// ...
}

Cocoa: How to avoid core-data duplicated relationships?

I have these entities:
ProductsEntity
name
orders [ProductsOrderRelationship]
OrderEntity
products [ProductsOrderRelationship]
ProductsOrderRelationship
order [OrderEntity]
product [ProductsEntity]
quantity
Now, I want to edit an existing order. I have a list of products available and cart.
Now I want to add these available products to the cart.
The code must check if the products exist, so it only increases the quantity.
But, by now, it is simply adding more relationships..
Let me share a piece of code!
The interface has a list on the left with the available products and a list on the right with the cart (order entity). Both have array controllers linked to my code. Then I have this action:
- (IBAction)addSelectedProducts:(id)sender {
NSArray *firstSelectedProducts = [availableProductsController selectedObjects];
//Objects selected in the array controller
NSMutableArray *selectedProducts = [[NSMutableArray alloc] initWithCapacity:1];
//Here I will filter the repeated ones
NSMutableSet *newProducts = [NSMutableSet set];
//This is the final value to change in the current order entry.
NSMutableSet *oldProducts = [orderManagedObject valueForKey:#"products"];
//This is the old value I will change.
//Here we filter every repeated entries:
if ( [firstSelectedProducts count] > 0 ) {
for (id object in firstSelectedProducts) {
if (![oldProducts containsObject:object]) {
[selectedProducts addObject:object];
}
}
}
//Here we create objects in the relationship entity:
for (int i = 0; i < [selectedProducts count]; i++) {
// Create new relationship.
NSManagedObject *newProductObject = [
NSEntityDescription
insertNewObjectForEntityForName:#"ProductsOrderRelationship"
inManagedObjectContext:managedObjectContext
];
[newProductObject setValue:[selectedProducts objectAtIndex:i] forKey:#"product"];
[newProductObject setValue:orderManagedObject forKey:#"order"];
[newProducts addObject:newProductObject];
[newProductObject release];
}
[newProducts unionSet:oldProducts];
//Join old products and new products.
[orderManagedObject setValue:newProducts forKey:#"products"];
//Re-set the value.
//(... release stuff here)
}
I can't find a guide to this specific problem.. Any suggestions?
I'm guessing that firstSelectedProducts contains ProductsEntity objects and oldProducts contains ProductsOrderRelationship objects. If that's true, the problem is that...
if (![oldProducts containsObject:object]) {
...will never match anything.
(What you call ProductsOrderRelationship is often called a LineItem. Changing the name of the class and its associated variables might make the logic clearer.)

How can I create temporary records of Linq-To-Sql types without causing duplicate key problems?

I have code that generates records based on my DataGridView. These records are temporary because some of them already exist in the database.
Crop_Variety v = new Crop_Variety();
v.Type_ID = currentCropType.Type_ID;
v.Variety_ID = r.Cells[0].Value.ToString();
v.Description = r.Cells[1].Value.ToString();
v.Crop = currentCrop;
v.Crop_ID = currentCrop.Crop_ID;
Unfortunately in this little bit of code, because I say that v.Crop = currentCrop,
now currentCrop.Crop_Varieties includes this temporary record. And when I go to insert the records of this grid that are new, they have a reference to the same Crop record, and therefore these temporary records that do already exist in the database show up twice causing duplicate key errors when I submit.
I have a whole system for detecting what records need to be added and what need to be deleted based on what the user has done, but its getting gummed up by this relentless tracking of references.
Is there a way I can stop Linq-To-Sql from automatically adding these temporary records to its table collections?
I would suggest revisiting the code that populates DataGridView (grid) with records.
And then revisit the code that operates on items from a GridView, keeping in mind that you can grab bound item from a grid row using the following code:
public object GridSelectedItem
{
get
{
try
{
if (_grid == null || _grid.SelectedCells.Count < 1) return null;
DataGridViewCell cell = _grid.SelectedCells[0];
DataGridViewRow row = _grid.Rows[cell.RowIndex];
if (row.DataBoundItem == null) return null;
return row.DataBoundItem;
}
catch { }
return null;
}
}
It is also hard to understand the nature of Crop_Variety code that you have posted. As the Crop_Variety seems to be a subclass of Crop. This leads to problems when the Crop is not yet bound to database and potentially lead to problems when you're adding Crop_Variety to the context.
For this type of Form application I normally have List _dataList inside form class, then the main grid is bound to that list, through ObjectBindingList or another way. That way _dataList holds all data that needs to be persisted when needed (user clicked save).
When you assign an entity object reference you are creating a link between the two objects. Here you are doing that:
v.Crop = currentCrop;
There is only one way to avoid this: Modify the generated code or generate/write your own. I would never do this.
I think you will be better off by writing a custom DTO class instead of reusing the generated entities. I have done both approaches and I like the latter one far better.
Edit: Here is some sample generated code:
[global::System.Data.Linq.Mapping.AssociationAttribute(Name="RssFeed_RssFeedItem", Storage="_RssFeed", ThisKey="RssFeedID", OtherKey="ID", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
public RssFeed RssFeed
{
get
{
return this._RssFeed.Entity;
}
set
{
RssFeed previousValue = this._RssFeed.Entity;
if (((previousValue != value)
|| (this._RssFeed.HasLoadedOrAssignedValue == false)))
{
this.SendPropertyChanging();
if ((previousValue != null))
{
this._RssFeed.Entity = null;
previousValue.RssFeedItems.Remove(this);
}
this._RssFeed.Entity = value;
if ((value != null))
{
value.RssFeedItems.Add(this);
this._RssFeedID = value.ID;
}
else
{
this._RssFeedID = default(int);
}
this.SendPropertyChanged("RssFeed");
}
}
}
As you can see the generated code is establishing the link by saying "value.RssFeedItems.Add(this);".
In case you have many entities for wich you would need many DTOs you could code-generate the DTO classes by using reflection.

Resources