I have a xamarin forms application that receives data from the database. The database gives "Car" data back. Those objects all have a couple of properties. On of those properties decides what kind of view should be shown on the screen. So a car could have a property named "TypeOfView" with a value "Entry" or "Picker" etc..
The problem is a follows: How can I dynamically create views based on that property and how can that be bind to objects in a list in the viewmodel?
// This is the codebehind where UI controls get created
BindingContext = DependencyInjectionService.Get<CheckListEditViewModel>();
var stack = new StackLayout()
{
Orientation = StackOrientation.Vertical,
Padding = 5
};
for (int i = 0; i < (BindingContext as CheckListEditViewModel).CheckListItems.Count; i++)
{
var item = (BindingContext as CheckListEditViewModel).CheckListItems[i];
var description = new Label()
{
Text = item.Description
};
stack.Children.Add(description);
if ((item.ChecklistItemType == Domain.ChecklistItemType.Number))
{
var numerEntry = new Entry();
numerEntry.Keyboard = Keyboard.Numeric;
numerEntry.TextChanged += MyMethod;
numerEntry.SetBinding(Entry.TextProperty, new Binding(mode: BindingMode.TwoWay, path: "Value", source: item));
stack.Children.Add(numerEntry);
// this is to test if the binding worked
var testLabelBindingTesting = new Label();
testLabelBindingTesting.SetBinding(Label.TextProperty, new Binding(mode: BindingMode.TwoWay, path: "Value", source: item));
stack.Children.Add(testLabelBindingTesting);
}
else if ((item.ChecklistItemType == Domain.ChecklistItemType.Email))
{
var numerEntry = new Entry();
numerEntry.Keyboard = Keyboard.Email;
stack.Children.Add(numerEntry);
}
}
Content = stack;
// The list is in the viewmodel class:
public ObservableCollection<ChecklistItem> CheckListItems { get; set; }
Related
After user authentication I'm supposed to change the user menu based on the roles of the user.
To do this, I created a service which fetched the menu the user is expected to see:
public List<MenuStructure> LoadCompleteMenuRole(string role)
{
List<MenuStructure> resultList = null;
var menuHeaders = LoadMenuHeadersForTheGivenRole(role);
if (menuHeaders != null && menuHeaders.Count > 0)
{
resultList = new List<MenuStructure>();
foreach (var menuHeader in menuHeaders)
{
var menuStructure = new MenuStructure
{
MenuName = menuHeader.HeaderName,
Caption = menuHeader.Caption
};
var menuDetails = LoadMenuDetailsForTheGivenHeader(menuHeader.Id);
if (menuDetails != null && menuDetails.Count > 0)
{
menuStructure.MenuElements = new List<MenuElement>();
foreach (var menuDetail in menuDetails)
{
var menuElement = new MenuElement
{
ElementName = menuDetail.DetailName,
ElementCaption = menuDetail.Caption,
Destination = menuDetail.Destination
};
menuStructure.MenuElements.Add(menuElement);
}
}
resultList.Add(menuStructure);
}
}
return resultList;
}
My problem? Where do I implement the service so the menus get loaded in every razor page I create?
I have a list with objects. Those objects all have properties. I loop through this list in the code behind. Based on a specific property of each item, I decide what view I should create.
That can be a button, picker etc.. At this moment I have reached from server to UI. But right now I need to go back from UI to server, I think that I need binding for that but I am unable to accomplish that. How can I achieve this?
My code:
var stack = new StackLayout()
{
Orientation = StackOrientation.Vertical,
Padding = 5
};
for (int i = 0; i < (BindingContext as CheckListEditViewModel).CheckListItems.Count; i++)
{
var item = (BindingContext as CheckListEditViewModel).CheckListItems[i];
var description = new Label();
description.Text = item.Description;
stack.Children.Add(description);
if ((item.ChecklistItemType == Domain.ChecklistItemType.Number))
{
var numerEntry = new Entry();
numerEntry.Keyboard = Keyboard.Numeric;
stack.Children.Add(numerEntry);
}
}
Content = stack;
I try to use my custom class which I have created in my script (the script is written in Nashorn) and after that I try to use this custom class to fill in as items in combobox. I know that if I want to see correct values in combobox that the class has to override method toString, but in this case I do not know much how can be overriden this method in my custom class written in Nahorn.
Below I provide my code where the variables cmbCategories is JavaFX combobox and CategoryItem which I try to use as object to fill in the items in combobox and display as category name.
I would appreciate any suggestion or ideas how can be this problem resolved.
var ClientBuilder = Java.type("javax.ws.rs.client.ClientBuilder")
var Platform = Java.type("javafx.application.Platform")
var Executors = Java.type("java.util.concurrent.Executors")
var Response = Java.type("javax.ws.rs.core.Response")
var String = Java.type("java.lang.String")
var List = Java.type("java.util.ArrayList")
Executors.newSingleThreadExecutor().execute(function () {
print("Calling for category data...")
var categoryData = ClientBuilder
.newClient()
.target(String.format("%s%s", "http://localhost:8080", "/client/action/categories"))
.request()
.get()
if(categoryData.getStatus() == Response.Status.OK.getStatusCode()) {
var categories = JSON.parse(categoryData.readEntity(String.class))
var categoryItems = new List();
for each (var category in categories) {
categoryItems.add(new CategoryItem(category.id, category.category))
}
Platform.runLater(function() {
cmbCategory.getItems().addAll(categoryItems);
});
} else {
print(categoryData.getEntity().toString());
}
})
function CategoryItem(id, name) {
this.id = id;
this.name = name;
this.toString = function () {
return this.name;
}
}
Use the ScriptEngine to retrieve an appropriate string in the cellValueFactory of the ComboBox.
Simplified example
#Override
public void start(Stage primaryStage) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
final ScriptEngine engine = manager.getEngineByMimeType("application/javascript");
ComboBox<Object> comboBox = new ComboBox();
comboBox.setCellFactory(c -> new ListCell<Object>() {
#Override
protected void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText("");
} else {
Bindings bindings = new SimpleBindings();
bindings.put("a", item);
try {
// use script engine to retrieve text
setText(Objects.toString(engine.eval("a.name", bindings)));
} catch (ScriptException ex) {
setText("Error");
}
}
}
});
comboBox.setButtonCell(comboBox.getCellFactory().call(null));
Bindings b = new SimpleBindings();
b.put("cmbCategory", comboBox);
engine.eval("function CategoryItem(id, name) {this.id = id;this.name = name;}\n"
+"var Platform = Java.type(\"javafx.application.Platform\")\n"
+ "var categories = [new CategoryItem(1, 'a'), new CategoryItem(2, 'b'), new CategoryItem(3,'c')]\n"
+ "for each (var category in categories) {cmbCategory.getItems().add(category);}", b);
Scene scene = new Scene(new StackPane(comboBox));
primaryStage.setScene(scene);
primaryStage.show();
}
I don't see the purpose of using JavaScript for this though. Everything you do in the javascript code could be done from java code more efficiently...
I have telerik REST web API(ASP.NET ) which is working fine. Now I need to localize the reports (report are in .trdx extension).
From documentation of telerik I found the code which have place in my BaseTelerikReportsController but this also not working, and even not show any error.
Telerik Localization Documentation
public class BaseTelerikReportsController : ReportsControllerBase
{
static readonly Telerik.Reporting.Services.ReportServiceConfiguration ConfigurationInstance;
static BaseTelerikReportsController()
{
var resolver = new CustomReportResolver();
//Create new CultureInfo
var cultureInfo = new System.Globalization.CultureInfo("aa-iq"); //<-- Line 1
// Set the language for static text (i.e. column headings, titles)
System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo; //<-- Line 2
var reportsPath = HttpContext.Current.Server.MapPath("~/Reports");
ConfigurationInstance = new Telerik.Reporting.Services.ReportServiceConfiguration
{
HostAppId = "TBReportApp",
ReportResolver = resolver,
// ReportResolver = new ReportFileResolver(reportsPath),
Storage = new Telerik.Reporting.Cache.File.FileStorage(),
};
}
public BaseTelerikReportsController()
{
ReportServiceConfiguration = ConfigurationInstance;
}
}
Note
There is a similar question but don't guide me to any right direction Here
Update 1
I have added below function in Global.asax.cs.
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
//Create new CultureInfo
var cultureInfo = new System.Globalization.CultureInfo("ar");
// Set the language for static text (i.e. column headings, titles)
System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
// Set the language for dynamic text (i.e. date, time, money)
System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
}
After above line (see image) data under red mark is localize but i need to localize yellow one(i.e heading)
I figure out how to localize the report header. Following are the some summarized steps.
Add App_GlobalResources folder and .resx accordingly your languages (See the figure 1-1).
Send language attribute from 'HTML5 Viewer'.
var viewer = $("#report-viewer").data("telerik_ReportViewer");
var model = {
//other attributes
Language: this.selectedLanguage //Here value may be ,en Or ar
};
viewer.reportSource({
report: reportSettings,
parameters: model
});
On server side based on that attribute change label accordingly.
private static void Localization(ref Report reportInstance)
{
ResourceManager currentResource = null;
switch (_language)
{
case "en":
currentResource = new ResourceManager("Resources.en", System.Reflection.Assembly.Load("App_GlobalResources"));
break;
case "ar":
currentResource = new ResourceManager("Resources.ar", System.Reflection.Assembly.Load("App_GlobalResources"));
break;
}
// var MyResourceClass = new ResourceManager("Resources.ar", System.Reflection.Assembly.Load("App_GlobalResources"));
ResourceSet resourceSet = currentResource.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string key = entry.Key.ToString();
string value = entry.Value.ToString();
var items = reportInstance.Items.Find(key,true);
foreach (var singleItem in items)
{
var singleItemType = singleItem.GetType();
//if (singleItem.GetType().FullName == "") ;
if (singleItemType.FullName == "Telerik.Reporting.TextBox")
{
var castItem = (Telerik.Reporting.TextBox) singleItem;
castItem.Value = value;
}
}
}
}
On Telerik Standalone Report Designer
Change your report(.trdx) Textbox value which matches your .resxname value pair.
Resource file values
I using openxml to create a powerpoint from an web app.I created a ppt with charts and opened ppt in openxml sdk productivity tool and code which was generated with that i modified the chart data which is coming from database,Code for which i created to modify the chart data as
created a class for the code in the sdk,in that CreatePart() i added these links
ChartPart chartPart1 = slidePart1.AddNewPart<ChartPart>("rId3");
GenerateChartPart1Content(chartPart1);
// This is below code added
#if true // Injects the chart part modification process
var chartModifier1 = new ChartPartModifier();
chartModifier1.UpdateSecondChartPart(chartPart1);
#endif
EmbeddedPackagePart embeddedPackagePart1 = chartPart1.AddNewPart<EmbeddedPackagePart>("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "rId2");
GenerateEmbeddedPackagePart1Content(embeddedPackagePart1);
and created a class for ChartPartModifier()
public void UpdateSecondChartPart(ChartPart chartPart)
{
// Searchs SeriesText and its Values to replace them with your dynamic data
var seriesLabels = chartPart.ChartSpace.Descendants<SeriesText>().ToList();
var seriesValues = chartPart.ChartSpace.Descendants<Values>().ToList();
var categoryAxis = chartPart.ChartSpace.Descendants<CategoryAxisData>().ToList();
for (int i = 0; i < this._lineSecCharts.Count; ++i)
{
var yourLine = this._lineSecCharts[i];
var label = seriesLabels[i].Descendants<NumericValue>().FirstOrDefault();
var values = seriesValues[i].Descendants<NumericValue>().ToList();
var categories = categoryAxis[i].Descendants<NumericValue>().ToList();
// Replaces the label of the series
label.Text = yourLine.Label;
// Replaces the values of the series
for (int valIdx = 0; valIdx < values.Count(); ++valIdx)
{
values[valIdx].Text = yourLine.Plots[valIdx].Value.ToString();
categories[valIdx].Text = yourLine.Plots[valIdx].Category;
}
}
}
Like this is there any way to modify the data in the table,If so can any one provide me the solution is much appreciated.
I found answer after a research i'm able to update the table values from database using openxml
the below code which(if condition) added between table appending the rows and graphicdata appending
table1.Append(tableProperties1);
table1.Append(tableGrid1);
table1.Append(tableRow1);
table1.Append(tableRow2);
table1.Append(tableRow3);
table1.Append(tableRow4);
table1.Append(tableRow5);
table1.Append(tableRow6);
table1.Append(tableRow7);
#if true // Injects the table modification process
TableModifier tableModifier = new TableModifier();//Create a class
tableModifier.UpdateTable(table1);//Send the table object of which you wanted to update
#endif
graphicData1.Append(table1);
graphic1.Append(graphicData1);
In class of TableModifier
using DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Packaging;
public class TableModifier
{
public TableModifier()
{
this.SetupDataSource();
}
public void UpdateTable(Table table)
{
var rows = table.Descendants<TableRow>().ToList();
for (int r = 0; r < rows.Count(); ++r)
{
var yourRow = this._rows[r];
var cells = rows[r].Descendants<TableCell>().ToList();
for (int c = 0; c < cells.Count(); ++c)
{
var yourCell = yourRow.Cells[c];
var text = cells[c].Descendants<Text>().FirstOrDefault();
if (text != null)
{
text.Text = yourCell.Value;
}
}
}
}
private void SetupDataSource()
{
this._rows.Add(new Row()
{
Cells = new List<Cell>()
{
new Cell(){ Value = "Products" },
new Cell(){ Value = "2010" },
new Cell(){ Value = "2011" },
new Cell(){ Value = "2012" },
}
});
for (int i = 0; i < 6; ++i)
{
var productName = string.Format("Product {0}", (char)(i + 'A'));
this._rows.Add(new Row()
{
Cells = new List<Cell>()
{
new Cell(){ Value = productName },
new Cell(){ Value = "10%" },
new Cell(){ Value = "20%" },
new Cell(){ Value = "30%" },
}
});
}
}
#region Private Data Structure
private class Row
{
public List<Cell> Cells { get; set; }
}
private class Cell
{
public string Value { get; set; }
}
#endregion
private List<Row> _rows = new List<Row>();
}