OnChange in MudBlazor RadioButtonGroup - events

I am new to Blazor and MudBlazor. I am using a and I want to call an event when the selection changes. The documentation show there is a EventCallback method but there are no syntax examples. I have been searching a good part of the day but cannot find an example. Can anyone please share some simple code? I know I can bind to a variable, and I initially did that. What I want is to call code and do some different code based on the selected value. Seems to be easier to do in Blazor syntax vs MudBlazor.
I appreciate any help.
Thank you

<MudRadioGroup T="string" SelectedOption="#SelectedOption" SelectedOptionChanged="OnSelectedOptionChanged">
<MudRadio Option="#("Radio 1")" Color="Color.Primary">Primary</MudRadio>
<MudRadio Option="#("Radio 2")" Color="Color.Secondary">Secondary</MudRadio>
<MudRadio Option="#("Radio 3")">Default</MudRadio>
<MudRadio Option="#("Radio 4")" Color="Color.Primary" Disabled="true">Disabled</MudRadio>
</MudRadioGroup>
#code {
public string SelectedOption { get; set; }
private void OnSelectedOptionChanged(string selectedOption)
{
SelectedOption = selectedOption;
// call your stuff
}
}
https://try.mudblazor.com/snippet/mOQGYtGKUpgnQxqe

Related

How can I code a class to receive a property for use with custom renderers?

I have seen this coding style:
public CustomTextCell()
{
}
public static readonly BindableProperty IsCheckedProperty =
BindableProperty.Create(
"IsChecked", typeof(bool), typeof(CustomTextCell),
defaultValue: false);
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
}
and this:
public class ExtViewCell : ViewCell
{
public bool NoTap { get; set; }
}
Can someone help explain the difference. Is one serving a different function from the other? In my case all I need is to pass to a custom renderer the value of NoTap. Should I code it like in the first or second example?
The second one is a POCO - a plain old C# object - that is relatively self-explanatory, but serves not much more purpose that holding data - and not that much in this case.
The first one is a bit more interesting, especially in the context of MVVM. SetValue does more than just setting the value, but will (in most cases) raise PropertyChanged event (see INotifyPropertyChanged), to notify subscribers that, well, a property has changed.
Now how does this relate to your custom renderer? You could implement the property in your view as a plain property - i.e. without notifications - and it might work (cannot tell, though, since I do not know your custom renderer) when setting IsChecked initially (and without binding). Anyway, imagine you'll update the value of IsChecked. You do so from your code and wonder, why this change is not reflected in your custom renderer. But how is your renderer supposed to know? Polling each and every property might be possible for smaller forms, but is a terrible waste of resources. (And Xamarin.Forms just does not work this way.) You'll page/view has to tell your custom renderer, that something has changed. INotifyPropertyChanged to the rescue. In your custom renderer you can subscribe to PropertyChanged event and react to IsChecked being changed, updating your native view.

How to pursuade the ApiExplorer to create documentation for ExpandoObject?

I've created a very neat way of implementing a PATCH method for my Web.API project by making use of an ExpandoObject as a parameter. As illustrated below:
[HttpPatch, Route("api/employee/{id:int}")]
public IHttpActionResult Update(int id, [FromBody] ExpandoObject employee)
{
var source = Repository.FindEmployeeById(id);
Patch(employee, source);
Repository.SaveEmployee(source);
return Ok(source);
}
However, when generating documentation ApiExplorer is at a loss as to what to do with the ExpandoObject, which is totally understandable. Would anyone have any ideas on how to manipulate the ApiExplorer to provide some sensible documentation?
My idea was to maybe introduce an new attribute which points to the actual Type that is expected:
public IHttpActionResult Update(int id, [FromBody, Mimics(typeof(Employee))] ExpandoObject employee)
{
...
}
But I have no idea where to start, any ideas or suggestions are welcome.
So this has been the source of some late evenings in order to get the Api Explorer to play along with our developed Http Patch mechanism. Truth be told, I'd probably should do a bit of a proper write up to full explain the mechanics behind the whole idea. But for those of you who landed on this page because you want the Api explorer to use a different type in the documentation, this is where you need to look:
Open HelpPageConfigurationExtensions.cs and locate the following method:
//File: Areas/HelpPage/HelpPageConfigurationExtensions.cs
private static void GenerateRequestModelDescription(HelpPageApiModel apiModel, ModelDescriptionGenerator modelGenerator, HelpPageSampleGenerator sampleGenerator)
{
....
}
this is the location where the parameter information is available to you and also provides you with the ability to replace/substitute parameter information with something else. I ended up doing the following to handle my ExpandoObject parameter issue:
if (apiParameter.Source == ApiParameterSource.FromBody)
{
Type parameterType = apiParameter.ParameterDescriptor.ParameterType;
// do something different when dealing with parameters
// of type ExpandObject.
if (parameterType == typeof(ExpandoObject))
{
// if a request-type-attribute is defined, assume the parameter
// is the supposed to mimic the type defined.
var requestTypeAttribute = apiParameter.ParameterDescriptor.GetCustomAttributes<RequestTypeAttribute>().FirstOrDefault();
if (requestTypeAttribute != null)
{
parameterType = requestTypeAttribute.RequestType;
}
}
}
Just, note that the RequestTypeAttribute is something I devised. My WebApi endpoint looks like this now:
public IHttpActionResult Update(int id,
[FromBody, RequestType(typeof(Employee))] ExpandoObject employee)
Thank you to everyone who took time to look into the problem.

Make changes to buttons and labels in an XML Ribbon during run-time

I know there are several topics already on stackoverflow, but nothing that actually solves the problem. Here it is:
Because of some inherent problems with Ribbon Designer I decided to build my next Excel AddIn using XML Ribbon.
However, occasionally I need to make changes to the controls in the ribbon based on user selections. For example I need to change the text of a label, and also make some of the controls disabled in some cases. And here's where I hit a brick wall. It looks like there's no way to do it. I tried to put the logic in the onAction callback as follows:
public void LabelAction(IRibbonControl control)
{
LabelControl label = (LabelControl)control;
label.Label = "changed text";
}
But this cast doesn't work because apparently IRibbonControl interface has nothing to do with the RibbonControl class that LabelConrol inherits from.
I was also not able to find any other way to access any of the XML ribbon controls. Is there even a solution to this? Or should I stick to Ribbon Designer?
You need to do this in a routine that sets the item label.
The xml would look like this:
<button id="SkLabelTest1" getLabel="GetLabelTest" onAction="SkLabelTest1"/>
<button id="SkLabelTest2" getLabel="GetLabelTest" onAction="SkLabelTest2"/>
The routine you are interested in is getLabel
I've done a noddy routine to demonstrate this.
First I added a property to ThisAddin.cs for it to read:
public string _labelTest = string.Empty;
public string LabelTest { get { return _labelTest; } set { _labelTest = value; } }
Then in my ribbon handling code I added the getLabel routine:
public string GetLabelTest(Office.IRibbonControl control)
{
switch (control.Id.ToLower())
{
case "sklabeltest2":
if (Globals.ThisAddIn.LabelTest != string.Empty)
return Globals.ThisAddIn.LabelTest;
else
return "Label Test 2";
default:
return "Label Test 1";
}
}
This works by the SkLabelTest1 button changing the text of SkLabelTest2 and then invalidating the control to force the ribbon to reload it:
public void SkLabelTest1(Office.IRibbonControl control)
{
Globals.ThisAddIn._labelTest = "Changed text";
Globals.ThisAddIn._ribbon.InvalidateControl("SkLabelTest2");
}
I've tested just in case and it changes the text OK. Hope this helps
I couldn't make a comment because of my reputation. As a comment to Charlie's post, it is a perfect solution but on my side, I had to change one part.
I changed public void SklabelTest1 function to this one below:
public void SkLabelTest1(Office.IRibbonControl control)
{
Globals.ThisAddIn._labelTest = "Changed text";
this.ribbon.InvalidateControl("SkLabelTest2");
}
And also added this in the beginning of my ribbon class.
private Office.IRibbonUI ribbon;
I hope it helps.

A simple RequiredField validator really this complex?

Using the INotifyDataErrorInfo I have validation methods in my setters of my properties, this works fine if I change the field value and then leave the control (change focus) the setter gets fired and validation occurs and the UI is notified, but using that interface, if the user just presses submit how can I do something similar to RequiredField like in asp.net, I can't seem to find a clear cut example on any forum or blog :(
I'm using Silverlight 4 WCF RIA and the mvvm-light toolkit, thats it. I hope im not over complexing this, because it seems like it should be so simple but can't seem to figure out a solution.
Thank you for all your help, suggestions and pointers!!!
Finally found a simple solution... Please let me know if anyone has a more efficient way of doing this :)
private void Validate()
{
ValidationContext validationContext = new ValidationContext(this, null, null);
ICollection vr = new List();
Validator.TryValidateObject(this, validationContext, vr, true);
if (vr.Count >= 1)
{
foreach (var item in vr)
{
ManageErrors(((string[])item.MemberNames)[0], new List() { item.ErrorMessage }, true);
}
}
}
The Manage Errors method is the simple implementation of the INotifyDataErrorInfo that Jesse Liberty did here
any ways now when my submit method gets called (using mvvm-light) in my viewModel i call this and bam all properties validated using simple dataAnnotations
ie
[Required(ErrorMessage = "Is Required", AllowEmptyStrings = false)]
public string SelectedStatus
{
get { return _selectedStatus; }
set
{
_selectedStatus = value;
RaisePropertyChanged("SelectedStatus");
}
}
Not the most elegant way of doing it but... by god I could not find anyone validating on a submit!?!?

Are there page checkers in WATIN which execute on each page load?

I am writing automation scripts using WATIR and WATIN. Watir has something called page checkers, which are code snippets that run on each page load. Is there something similar in WATIN ? I want a piece of code to run on each page load. Generally this is used to check for page errors or page loading images.
It is not really that easy to tell when page loads. I quickly googled about that page checkers in Watir, that you mentioned and found an article about page checkers in Watir. See first comment bellow the article. AFAIK it's really similar in WatiN.
Unfortunately, I don't see any similar functionality in WatiN (no event is fired after internal call to WaitForComplete. The easiest thing you could do is to subclass eg. IE class:
class MyIE : IE
{
public MyIE(string url) : base(url) { } //TODO: add constructors
public override void WaitForComplete(int waitForCompleteTimeOut)
{
base.WaitForComplete(waitForCompleteTimeOut);
Console.WriteLine("Page has been loaded");
}
}
However, the situation will be similar to described in mentioned comment (runs a lot more regularly than just page load).
I think that better approach would be using Page class from WatiN library. It is well documented. Example for watin.org webpage:
var ie = new MyIE("http://watin.org/");
var homePage = ie.Page<HomePage>();
Console.WriteLine(homePage.FirstFeature);
homePage.DocumentationLink.Click();
var documentationPage = ie.Page<DocumentationPage>();
Console.WriteLine(documentationPage.FAQLink.Url);
To run that code you need following classes:
abstract class WatiNBasePage : Page
{
[FindBy(Id = "header")]
public Div HeaderDiv { get; set; }
public Link HomeLink { get { return HeaderDiv.Link(Find.ByText("Home")); } }
public Link DocumentationLink { get { return HeaderDiv.Link(Find.ByText("Documentation")); } }
protected override void InitializeContents()
{
base.InitializeContents();
VerifyDocumentProperties(UnverifiedDocument, errorMessage => { throw new Exception(errorMessage); }); //TODO: modify if needed
}
protected override void VerifyDocumentProperties(Document document, Page.ErrorReporter errorReporter)
{
base.VerifyDocumentProperties(document, errorReporter);
if (!HomeLink.Exists)
errorReporter("HomeLink not exists");
//TODO: more checks here
}
}
class HomePage : WatiNBasePage
{
[FindBy(Id = "features")]
public Table FeatureTable { get; set; }
public string FirstFeature { get { return FeatureTable.Span(Find.First()).Text; } }
}
class DocumentationPage : WatiNBasePage
{
[FindBy(Text = "Frequently Asked Questions")]
public Link FAQLink { get; set; }
}
Basically you need to implement VerifyDocumentProperties. Above code will check if HomeLink exists, but maybe you would like to check if DocumentationLink exists etc. The second thing is to modify call to VerifyDocumentProperties. Now, if verification fails, Exception will be thrown after calling ie.Page<T>() (where T is a subclass of WatinBaseClass).
In my opinion, even if you don't need to use "page checkers", using Page class is still really useful and clarifies the code, so I really recommend using it. I regret that I haven't discovered it when I was starting work with WatiN.

Resources