SfGrid RowSelection event handling reloads data - razor

I have the following code in a Razor component:
<SfGrid TValue="DataItem" ID="Grid"
DataSource="#DataList01"
AllowSorting="false"
AllowFiltering="false"
AllowSelection="true"
AllowPaging="false">
<GridSelectionSettings Type="Syncfusion.Blazor.Grids.SelectionType.Single"></GridSelectionSettings>
<GridColumns>
<GridColumn Field="#DataText" HeaderText="Data"></GridColumn>
</GridColumns>
</SfGrid>
When using that code, I can select any row.
However, if I add the event handling:
<SfGrid TValue="DataItem" ID="Grid"
DataSource="#DataList01"
AllowSorting="false"
AllowFiltering="false"
AllowSelection="true"
AllowPaging="false">
<GridSelectionSettings Type="Syncfusion.Blazor.Grids.SelectionType.Single"></GridSelectionSettings>
<GridEvents TValue="DataItem" RowSelected="#(row=> SelectedRow = row.Data)" />
<GridColumns>
<GridColumn Field="#DataText" HeaderText="Data"></GridColumn>
</GridColumns>
</SfGrid>
#code {
public DataItem SelectedRow { get; set; }
}
The selection disappears after clicking it and the data is reloaded.
Can you tell me why? What should I change?

Well, the answer is in the invisible details.
The data source of the grid in the code was significant after all:
DataSource="#DataList01"
It is a gRPC-based stream and it turned out that having it stream data caused the grid to be refreshed on every event interaction.
After using a local copy of the data it provided, the selection works normally.

Can you please share the below information regarding the issue you are facing. Because we are not able to reproduce the reported issue at our end while preparing a sample using your code example and latest version Syncfusion.Blazor Nuget package 18.4.0.47.
Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/DataGrid-2097295582
Share the following details, If you are still facing the reported issue
Share your Syncfusion.Blazor Nuget package version details.
Share the video demonstration of the issue.
Try to reproduce the reported issue in the provided sample.

Related

Blazor component is rendered but no lifecycle methods are called, no other methods can be invoked

I have a pretty standard Razor pages project, and I've recently introduced Blazor components into the project. I've added the _Host.cshtml, App.razor, and the other requirements to get Blazor working. The Blazor components work fine when I'm at an endpoint that is exclusively Blazor components. However, I want to embed Blazor components within my current .cshtml pages using something like
#(await Html.RenderComponentAsync<EditorComponent>(RenderMode.Server, new { Id = Model.Id}))
withing my cshtml page. This syntax renders the component fine, but it doesn't run any of the Blazor lifecycle methods(OnAfterRenderAsync) or even something like a button calling back to a Task, in my EditorComponent component.
I've included the
<script src="~/_framework/blazor.server.js"></script>
at the end of element on my layout page. Am I missing something to get this working?
I think you might need to use the component tag helper instead.
Docs
<component type="typeof(EditorComponent)" render-mode="Server" param-Id=#Model.Id/>
As you've not provided a lot of code, I've built this code to try and reproduce your problem.
I can't: it works as I would expect it to. So unless either answer above solves your problem, you'll need to provide more code.
Start point Blazor Server template.
New razor page - _Test.cshtml
#page "/Test"
#namespace BlazorApp8.Pages
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#{
Layout = "_Layout";
}
<h1>Counter in a Page</h1>
<div class="m-2 p-2">
#(await Html.RenderComponentAsync<Counter>(RenderMode.Server, new { Starter = 6}))
</div>
Update Counter.razor to take a parameter.
[Parameter] public int Starter { get; set; } = 0;
protected override Task OnInitializedAsync()
{
currentCount = this.Starter;
return base.OnInitializedAsync();
}
Run and navigate to /Test.
I get the Counter page, OnInitialized sets the initial count to 6 and clicking on the button increments the counter.
Replace the blazor section in your _Layout.cshtml with =>
<head>
...
<base href="~/"/>
</head>
...
<script src="_framework/blazor.server.js" autostart="false" ></script>
<script>
Blazor.start({
configureSignalR: function(builder) {
builder.withUrl("_blazor");
}
});
</script>
...
Make sure to check your web console output. Blazor is likely throwing an error. This is pulled from every layout of every area in every app that I make. I've enjoyed a templated micro ui experience. Dotnet really makes it a breeze to proliferate your own designs via templates.

JavaFX WebView: link to anchor in document doesn't work using loadContent()

Note: This is about JavaFX WebView, not Android WebView (i. e. I have seen "Android Webview Anchor Link (Jump link) not working").
I display a generated HTML page inside a javafx.scene.web.WebView that contains anchors and links to those anchors like this:
<p>Jump to Introduction</p>
some text ...
<h1 id="introduction">Introduction</h1>
more text ...
I use this code to load the HTML into the WebView:
public void go(String location) {
try {
// read the content into a String ...
String html = NetUtil.readContent(new URL(location), StandardCharsets.UTF_8);
// ... and use loadContent()
webview.getEngine().loadContent(html);
} catch (IOException e) {
LOG.error(e);
}
}
Everything is rendered correctly, but if I click on the link named "Introduction", nothing happens.
The HTML however is correct, which I checked by instead using this code:
public void go(String location) {
// use load() to directly load the URL
webview.getEngine().load(location);
}
Now, everything worls fine.
The problem seems to be somehow because the document URL of the WebView is null when using loadContent(), but since it's a readonly property, I have no idea how to make it work.
I need to use loadContent(), because the HTML is generated on the fly, and if possible in any way, I don't want to have to write it out to a file just to make anchor links working. Is there a way to fix this?
EDIT
I filed a bug for JavaFX.
It's probably another WebEngine bug. A lot of that code is just a native libraries wrapped in api, so we can't modify it in runtime to fix some disabilities.
If you are able to change the structure of generated file you can implement scrolling to element in js:
<script>
function scrollTo(elementId) {
document.getElementById(elementId).scrollIntoView();
}
</script>
<a href='#' onclick=scrollTo('CX')>Jump to Chapter X</a>
<h2 id="CX">Chapter X</h2>
If you can't change the structure, there is some steps that I've made to try to fix it and some suggestions - at first I've set value of location by reflections after loadContent for sure:
Field locationField = WebEngine.class.getDeclaredField("location");
locationField.setAccessible(true);
ReadOnlyStringWrapper location = (ReadOnlyStringWrapper) locationField.get(engine);
location.set("local");
But in fact, keeping state of actual location is just an information for you and manipulating this changes nothing. I've also found a way to set url from js (just a long shot, we don't have any specific details why it's not working):
window.history.pushState("generated", "generated", '/generated');
Of course we can't because of:
SecurityError: DOM Exception 18: An attempt was made to break through the security policy of the user agent.
I think you should forget about loadContent(). You said that you didn't want to write generated content to file. A little dirty hack but really helpful for you could be wrapped http server on random and unused port in your application. You don't even need external libraries because Java has simple utilities like that:
HttpServer server = HttpServer.create(new InetSocketAddress(25000), 0);
server.createContext("/generated", httpExchange -> {
String content = getContent();
httpExchange.sendResponseHeaders(200, content.length());
OutputStream os = httpExchange.getResponseBody();
os.write(content.getBytes());
os.close();
});
server.setExecutor(null);
server.start();
You can also use another browser to display your page, e.g. JCEF (Java Chromium Embedded Framework).

Android ListView binding programmatically

There are many examples of doing this in axml, but I would like to have a complete binding using code behind. To be honest, I would like to have NO axml, but seems like creating all the controls programmatically is a nightmare.
I first tried the suggestions at:
MvxListView create binding for template layout from code
I have my list binding from code-behind, and I get six rows (so source binding is working); but the cells itself does not bind.
Then at the following url:
Odd issue with MvvmCross, MvxListViewItem on Android
Stuart has the following comment: Have looked through. In this case, I don't think you want to use DelayBind. DelayBind is used to delay the binding action until next time the DataContext is set. In Android's MvxAdapter/MvxListItemView case, the DataContext is passed in the ctor - so DataContext isn't set again until the cell is reused. (This is different to iOS MvxTableDataSource).
So in essence, the only example I see shows DelayBind, which shouldn't work.
Can someone please show me some examples... thanks in advance.
Added reply to Comments:
Cheesebaron, first of all, a huge thank you and respect for all your contributions;
Now, why not use axml? Well, as programmers, we all have our own preferences and way of doing stuff - I guess I am old school where we didn't have any gui designer (not really true).
Real reasons:
Common Style: I have a setup where Core has all the style details, including what all the colors would be. My idea is, each platform would get the style details from core and update accordingly. It's easy for me to create controls with the correct style this way.
Copy-Paste across platform (which then I can even have as linked files if I wanted). For example, I have a login screen with web-like verification, where a red error text appears under a control; overall on that screen I have around 10 items that needs binding. I have already got iOS version working - so starting on Droid, I copied the whole binding section from ios, and it worked perfectly. So, the whole binding, I can make it same across all platform... Any possible error in my way will stop at building, which I think is a major advantage over axml binding. Even the control creation is extremely similar, where I have helpers with same method name.
Ofcourse I understand all the additional layout that has to be handled; to be honest, it's not that bad if one really think it through; I have created a StackPanel for Droid which is based on WP - that internally handles all the layouts for child views; so for LinearLayout, all I do is setup some custom parameters, and let my panel deal with it. Relative is a different story; so far, I have only one screen that's relative, and I can even make it Linear to reduce my additional layout code.
So, from my humble point of view, for my style, code-behind creation allows me to completely copy all my bindings (I do have some custom binding factories to allow that), copy all my control create lines; then only adding those controls to the view is the only part that is different (then again, droid and WP are almost identical). So there is no way I can miss something on one platform and all are forced to be the same. It also allows me to change all the styles for every platform just by changing the core. Finally, any binding error is detected during compile - and I love that.
My original question wasn't about NOT using axml... it was on how to use MvxListView where all the binding is done in code-behind; as I have explained, I got the list binding, but not the item/cell binding working.
Thanks again in advance.
Here is part of my LoginScreen from droid; I think it's acceptable amount of code for being without axml file.
//======================================================================================================
// create and add all controls
//======================================================================================================
var usernameEntry = ControlHelper.GetUITextFieldCustom(this, "Username.", maxLength: 20);
var usernameError = AddErrorLabel<UserAuthorization, string>(vm => ViewModel.Authorization.Username);
var passwordEntry = ControlHelper.GetUITextFieldCustom(this, "Password.", maxLength: 40, secureTextEntry: true);
var passwordError = AddErrorLabel<UserAuthorization, string>(vm => ViewModel.Authorization.Password);
var loginButton = ControlHelper.GetUIButtonMain(this);
var rememberMe = new UISwitch(this);
var joinLink = ControlHelper.GetUIButtonHyperLink(this, textAlignment: UITextAlignment.Center);
var copyRightText = ControlHelper.GetUILabel(this, textAlignment: UITextAlignment.Center);
var copyRightSite = ControlHelper.GetUIButtonHyperLink(this, textAlignment: UITextAlignment.Center);
var layout = new StackPanel(this, Orientation.Vertical)
{
Spacing = 15,
SubViews = new View[]
{
ControlHelper.GetUIImageView(this, Resource.Drawable.logo),
usernameEntry,
usernameError,
passwordEntry,
passwordError,
loginButton,
rememberMe,
joinLink,
ControlHelper.GetSpacer(this, ViewGroup.LayoutParams.MatchParent, weight: 2),
copyRightText,
copyRightSite
}
};
I just came across a similar situation myself using Mvx4.
The first link you mentioned had it almost correct AND when you combine it from Staurts comment in the second link and just remove the surrounding DelayBind call, everything should work out ok -
public class CustomListItemView
: MvxListItemView
{
public MvxListItemView(Context context,
IMvxLayoutInflater layoutInflater,
object dataContext,
int templateId)
: base(context, layoutInflater, dataContext, templateId)
{
var control = this.FindViewById<TextView>(Resource.Id.list_complex_title);
var set = this.CreateBindingSet<CustomListViewItem, YourThing>();
set.Bind(control).To(vm => vm.Title);
set.Apply();
}
}
p.s. I have asked for an Edit to the original link to help others.

Weird behavior while Suppress "Bookmarks" button in SAPUI5, Fiori

Some times ago i've successfully suppressed the "Save as Tile" button that exists in the Standard Fiori App, MM_PO_APV:
// Standard application buttons (Remove Forward)
this.setHeaderFooterOptions({
oPositiveAction: {
sI18nBtnTxt: that.resourceBundle.getText("XBUT_APPROVE"),
onBtnPressed: jQuery.proxy(that.handleApprove, that)
},
oNegativeAction: {
sI18nBtnTxt: that.resourceBundle.getText("XBUT_REJECT"),
onBtnPressed: jQuery.proxy(that.handleReject, that)
},
onBack: jQuery.proxy(function() {
//Check if a navigation to master is the previous entry in the history
var sDir = sap.ui.core.routing.History.getInstance().getDirection(this.oRouter.getURL("master"));
if (sDir === "Backwards") {
window.history.go(-1);
} else {
//we came from somewhere else - create the master view
this.oRouter.navTo("master");
}
}, this),
// Remove the 'Save as Tile' button
bSuppressBookmarkButton : true
});
But they had updated the SAPUI5 version, I think the lastest, and it comes with a problem. The button is appearing, but with a weird behavior, as you can see:
All my code remains the same, and as I've seen on documentation API, it remains the same too.
Could you help me on how to resolve this?
Regards,
Andre
The most likely cause for this would be the UI5 version(the latest update that you mentioned).
Try one of these two things,
Clear cache and re-run the application
Revert to a previous UI5 version or update to a new version
Contact the respective support team(Scaffolding team I assume) if these don't help.
This should work:
//Prevent overflow button (...) in footer
this.oApplicationImplementation.oDHFHelper.oCommonHeaderFooterHelper.bAutomaticOverflow = false;
Put this code in the onInit method of the controller extension.

FLEX 4.0 Vgroup seems not to draw their elements

I got a component made with an spark Group for a survey, inside of it I have an algorithm that create the questions putting RadioButtons inside of a VGroup(dynamically).
The problem is that sometimes when I call the next question, I couldn't find why, they are not drawn unless I click the right mouse button so it appears normally.
public function nextQuestion(event:MouseEvent):void
{
destroyQuestion();
selectNextQuestion();
creatQuestion();
}
private function destroyQuestion(): void
{
vgSurvey.removeAllElements();
}
private function createQuestion(): void
{
for each(var answer: Answer in currentItem.arrayAnswers)
{
var radioAnswer: RadioButton = new RadioButton();
radioAnswer.id = answer.id;
radioAnswer.label = answer.label;
vgSurvey.addElement(radioAnswer);
}
}
<MXML>
...
<s:VGroup id="vgSurvey" >
</s:VGroup>
So, when I run the application and I move through the questions, sometimes, the question is not drawn (exemple: I'm at question 2 and I move to the third question and it's blank, but if i press the right button in my mouse the question suddenly appears. So I move to the fourth and everything seems right)
I apologize about my English and hope you guys can help me.
Looks like Flash Player problem, try installing older FP version.
Try changing container to Tile temporatily - you'll know whether the problem is in VGroup.
Try using different SDK version - you'll know if it's the problem of your 4.0 SDK (there are some bugs fixed for groups/layouts since 4.0).
Check if there are runtime exceptions firing during nextQuestion() execution by commenting out all your try/catch statements.