//this is my interface
public interface IPopupGrid
{
void PopupClosed(string key);
void PopupGridPageChanging(string key);
void PopupFilterButtonClicked(string key);
void PopupOkButtonClicked(string key);
void PopupGridSorting(string key);
}
//this is the class that implements the interface
//on buton click this loads a grid in modal popup extender
public partial class CustomerChargesMaster : IPopupGrid
{
public void PopupClosed(string key)
{
if (key == "Customer")
CloseCustomerPopup();
}
public void PopupGridPageChanging(string key)
{
if (key == "Customer")
ShowCustomerPopup();
}
public void PopupFilterButtonClicked(string key)
{
if (key == "Customer")
ShowCustomerPopup();
}
public void PopupOkButtonClicked(string key)
{
if (key == "Customer")
CustomerSelected();
}
public void PopupGridSorting(string key)
{
if (key == "Customer")
ShowCustomerPopup();
}
private void CloseCustomerPopup()
{
CustomerPopupExtender.Hide();
}
private void ShowCustomerPopup()
{
CustomerPopupExtender.Show();
}
protected void SelectCustomerButton_Click(object sender, EventArgs e)
{
CustomerPopup.CssClass = "";
CustomerPopupGrid.GridMode = PopupGridMode.SingleSelect;
CustomerPopupGrid.LoadPopupControl("Customer", this);
CustomerPopupExtender.Show();
}
private void CustomerSelected()
{
}
}
//code inside user control
public partial class GenericPopupGrid : System.Web.UI.UserControl
{
public void LoadPopupControl(string key, IPopupGrid caller)
{
if (string.IsNullOrEmpty(key))
return;
_key = key;
ViewState["PopupGridKey"] = key;
_caller = caller;
//Session["Caller"] = caller;
listModel = ModelFactory.GetPopupGridModel(_key);
if (listModel == null)
{
return;
}
PopupHeaderLabel.Text = listModel.GridTitle;
BindGenericPopupGridView();
GenericPopupGridView.BottomPagerRow.Visible = true;
}
protected void FilterOkButton_Click(object sender, EventArgs e)
{
//calling the caller class method to keep the popup open
_caller.PopupOkButtonClicked(_key);
}
}
I have a web user control with grid which I use to load different data depending upon the key passed
This is called as a popup using modal popup extender from a aspx page
Now doing any postback will close the grid
so i am using the interface to call the method in the caller page, which will keep the popup open
but this is not working as intended
If i add an EventHandler in the UserControl and attach a method in the aspx page then the popup remains open
Is there any other easier way to do this? I do not want to write the code to attach a method to even handler and the method itself in all the aspx pages that calls the popup.
Code is as above
Related
My problem is, the data which is date entered by user is doesn't after submit button. So I have fields in my registration page and A button to save in my database.
This is what I've tried.
//My Datepicker Design
`
<local:BirthdayDatePickerControl
TextColor="Black"
x:Name="entryField_DateOfBirth"
/>
`
The purpose that I create a custom control in my datepicker is to put an placeholder iny my datepicker field.
//my Birthdaypickercontrol.cs
`
public class BirthdayDatePickerControl : DatePicker
{
public event EventHandler ClearRequested;
// for my placeholder "birthdate"
public static readonly BindableProperty EnterTextProperty = BindableProperty.Create(propertyName: "Placeholder", returnType: typeof(string), declaringType: typeof(BirthdayDatePickerControl), defaultValue: default(string));
public string Placeholder { get; set; }
//function to clear data of my datepicker input
public void clear()
{
if (ClearRequested != null)
{
ClearRequested(this, EventArgs.Empty);
}
}
}
`
In my project.android, I create a birthday renderer.cs
//so this is my code
`
[assembly: ExportRenderer(typeof(BirthdayDatePickerControl), typeof(BirthdayDatePickerRenderer))]
public class BirthdayDatePickerRenderer : DatePickerRenderer
{
public BirthdayDatePickerRenderer(Context context) : base(context)
{
}
EditText editText;
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.DatePicker> e)
{
base.OnElementChanged(e);
//code for placeholder
if (Control != null)
{
Control.Text = "Birth Date";
}
//end here
//code start here for clearing the data in datepicker input field
editText = Control as EditText;
if (e.NewElement != null)
{
BirthdayDatePickerControl bdaydatePickerControl = e.NewElement as BirthdayDatePickerControl;
bdaydatePickerControl.ClearRequested += DatePickerControl_ClearRequested;
}
//end here
}
public void DatePickerControl_ClearRequested(object sender, EventArgs e)
{
editText.Text = string.Empty;
}
}
`
The codes I pasted will anyway, but..
Assuming in the onload of my registration page, The UI will be like this( pic for reference and ctto to google). After user choose birthdate, example 12/1/22 and hit submit button(all data save in to database). The problem is the placeholder "birthdate" remove/disappear Like this, then if I click the datepicker input field to check the date, the date is still pointing in 12/1/22. What I expected is after performing the ClearData(), the date should be reset in today's date.
//this is my ClearData() function
`
public void ClearData()
{
entryField_DateOfBirth.clear();// this is what I tried and got an bad ouput
}
`
You said:
What I expected is after performing the ClearData(), the date should be reset in today's date.
public void DatePickerControl_ClearRequested(object sender, EventArgs e)
{
editText.Text = string.Empty;
}
Change to this:
public void DatePickerControl_ClearRequested(object sender, EventArgs e)
{
BirthdayDatePickerControl birthdayDate = sender as BirthdayDatePickerControl;
birthdayDate.Date = DateTime.Now;
editText.Text = "Birth Date";
}
I'm using a webview in my Xamarin Forms project with Hybrid Renderer and webview, because I have to inject javascript code inside the page.
In my main project I have a CustomWebview.cs:
namespace ClotureSiadForms.Renderer
{
public class CustomWebView : WebView
{
public string js = "";
public CustomWebView()
{
Navigating+= WebViewNavigating;
Navigated+=WebViewNavigated;
}
private void WebViewNavigated(object sender, WebNavigatedEventArgs args)
{
EvaluateJavaScriptAsync(js);
}
public void WebViewNavigating(object sender, WebNavigatingEventArgs args)
{
if (args.Url.StartsWith("tel:"))
{
var tel = args.Url.Split(':')[1];
args.Cancel = true;
Xamarin.Essentials.PhoneDialer.Open(tel);
}
else if (!args.Url.StartsWith("http") || args.Url.EndsWith(".apk") || args.Url.EndsWith(".pdf") || args.Url.EndsWith(".zip"))
{
args.Cancel = true;
Xamarin.Essentials.Launcher.OpenAsync(args.Url);
}
}
}
}
In my Android project I have a HybridWebViewRenderer.cs:
[assembly: ExportRenderer(typeof(CustomWebView), typeof(HybridWebViewRenderer))]
namespace ClotureSiadForms.Droid.Renderer
{
internal class HybridWebViewRenderer : WebViewRenderer
{
public HybridWebViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
CustomWebView webview = e.NewElement as CustomWebView;
Control.Settings.JavaScriptEnabled = true;
Control.Settings.DomStorageEnabled = true;
Control.Settings.SavePassword = true;
}
}
}
}
As is, it worked and was able to download files
But as I needed basic authentication, I added a custom webviewclient inside HybridWebViewRenderer.cs:
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
CustomWebView webview = e.NewElement as CustomWebView;
Control.Settings.JavaScriptEnabled = true;
Control.Settings.DomStorageEnabled = true;
Control.Settings.SavePassword = true;
var login = Preferences.Get("login", "");
var password = Preferences.Get("password", "");
Control.SetWebViewClient(new AuthWebViewClient(login, password));
}
}
public class AuthWebViewClient : WebViewClient
{
private string Username;
private string Password;
public AuthWebViewClient(string username, string password)
{
Username = username;
Password = password;
}
public override void OnReceivedHttpAuthRequest(Android.Webkit.WebView view, HttpAuthHandler handler, string host, string realm)
{
handler.Proceed( Username,Password);
}
}
And authentication works, but WebViewNavigating is now called once, then the custom client is set and then WebViewNavigating is never more called.
Then my question is, can't I use basic auth without a custom client or is there a way to keep using my customwebview with the client ?
And authentication works, but WebViewNavigating is now called once, then the custom client is set and then WebViewNavigating is never more called.
I tested the code you provided and added Breakpoint to WebViewNavigating method. Even if you do not add webviewclient, it will only call WebViewNavigating once.
You can put the code in WebViewNavigating to ShouldInterceptRequest:
public class AuthWebViewClient : WebViewClient
{
...
public override WebResourceResponse ShouldInterceptRequest(Android.Webkit.WebView view, IWebResourceRequest request)
{
var url = request.Url;
...
}
}
Whenever the WebView begins loading a new page, it will call ShouldInterceptRequest.
I am using a tabbed app and I have a button on one tab, when the user clicks then it increments a Preference and I want to update its value on another tab that is Binded to a label. I tried to experiment with MVVM but I couldnt figure it out.
Page 1 view:
public partial class Page1View: ContentPage
{
public Page1View()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
Preferences.Set("Total", Preferences.Get("Total", 0)+1);
}
}
Page 2 Viewmodule:
public class Page2ViewModule : INotifyPropertyChanged
{
public int Total
{
get => Preferences.Get(nameof(Total), 0);
set
{
if (Preferences.Get(nameof(Total),0) == value)
return;
Preferences.Set(nameof(Total), value);
OnPropertyChanged(nameof(Total));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var changed = PropertyChanged;
if (changed != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Here's what I done with MessagingCenter. On the button click event I sent a message like this:
private void Button_Clicked(object sender, EventArgs e)
{
Preferences.Set("Total", Preferences.Get("Total", 0)+1);
MessagingCenter.Send<Page>(this, "test");
}
In the Page2 view module I added a constructor that subscribes to message:
public Page2ViewModule()
{
MessagingCenter.Subscribe<Page>(this, "test", (p) =>
{
Total = Preferences.Get(nameof(Total), 0);
});
}
And that still doesn't work. But I'm not sure would this be the best way to do it? Or is there a more efficient way?
For Jason's question: Page2 already been created and the Subscribe method execute before you call Send, I test at my side, Page2 is been created and the Subscribe method execute after you call Send, so I think it works fine using MessagingCenter to notify each page when the Preference has been updated.
Tab one Page.
private void btn1_Clicked(object sender, EventArgs e)
{
Preferences.Set("Total", Preferences.Get("Total", 0) + 1);
label1.Text = Preferences.Get("Total", 0).ToString();
MessagingCenter.Send<Page>(this, "test");
}
Tab two page.
<ContentPage.Content>
<StackLayout>
<Label Text="{Binding Total}" />
</StackLayout>
</ContentPage.Content>
public partial class Tab2 : ContentPage
{
public Tab2()
{
InitializeComponent();
this.BindingContext = new Page2ViewModule();
}
}
public class Page2ViewModule : ViewModelBase
{
private int _Total;
public int Total
{
get { return _Total; }
set
{
_Total = value;
RaisePropertyChanged("Total");
}
}
public Page2ViewModule()
{
MessagingCenter.Subscribe<Page>(this, "test", (p) =>
{
Total = Preferences.Get("Total", 0);
});
}
}
I am trying to call the event handler from droid side, however it doesn't get fired. everyone else works however this event doesn't get fired. I am not sure what am I doing wrong. I have my dependency service registered at MainActivity and set dependency in my service.
public partial class MainPage : ContentPage
{
DocumentResults results;
IScanService scanService;
public MainPage()
{
InitializeComponent();
results = new DocumentResults();
BindingContext = new MainPageViewModel();
System.Diagnostics.Debug.WriteLine("test cw");
Console.WriteLine("test cw");
scanService = DependencyService.Get<IScanService>();
scanService.ResultsParsedEvent += (s, ev) => { ResultsParsed(null, ev); };
}
void Button_Clicked(System.Object sender, System.EventArgs e)
{
scanService.ScanService();
if (!String.IsNullOrWhiteSpace(test))
{
scanService.Parsing(test);
}
}
private void ResultsParsed(DocumentResults results,EventArgs e)
{
Console.WriteLine("update ");
testLbl.Text = results.Name;
}
}
My interface
public interface IScanService
{
event EventHandler ResultsParsedEvent;
string ScanService();
void Parsing(string test);
void resultsParsed(DocumentResults results, EventArgs e);
}
Droid implementation
public class RegService : IScanService
{
public event EventHandler ResultsParsedEvent;
DocumentResults results;
public string Test;
public String ScanService()
{
Test = "scan";
return Test;
}
public void Parsing(string test)
{
Test = "parsing";
var results= new DocumentResults();
results.Name = Test;
Thread thread1 = new Thread(() => resultsParsed(results,null));
System.Threading.Thread.Sleep(10);
resultsParsed(results,null);
}
public void resultsParsed(DocumentResults results, EventArgs e)
{
ResultsParsedEvent?.Invoke(results, e);
}
}
I'm trying to create a factory pattern based on the CompositeControl class.
Everything is working fine. Except as I understand it I have to add the control back onto the placeholder control on my actual page. I've searched around for examples and got one to almost work expect it only worked on the first postback.
I've created a sample here and I'll post all the code here.
Code on my webpage, the most important here is I guess on OnInit where I'm trying to add the control back onto the placeholder, I guess this is what I might be doing wrong.
using SampleControls;
public partial class Test : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//Setup First Control
Session.Clear();
BaseCompositeControl ltb = new LabelTextBox();
PlaceHolder1.Controls.Add(ltb);
Session.Add("Control", ltb);
}
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// Check if the post back and recreate the control
if (IsPostBack)
{
int c = this.Form.Controls.Count;
for (int i = 0; i < Session.Count; i++)
{
if (Session[i].ToString().Contains("Control"))
{
this.PlaceHolder1.Controls.Add((BaseCompositeControl)(Session[i]));
}
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
//Get Postback Date
BaseCompositeControl oltb = (BaseCompositeControl)this.PlaceHolder1.Controls[0];
lblPstBck.Text = oltb.Text;
this.PlaceHolder1.Controls.Clear();
Session.Clear();
//Load next Control
BaseCompositeControl ltb = new LabelCheckBox();
PlaceHolder1.Controls.Add(ltb);
Session.Add("Control", ltb);
}
}
This is composite control classes, I don't know if I have to do something here to handle the viewstate or how?
public abstract class BaseCompositeControl : CompositeControl
{
protected string _Title;
public abstract string Text
{
get;
set;
}
public string Title
{
get { EnsureChildControls();
return _Title; }
set { EnsureChildControls();
_Title = value; }
}
protected override void CreateChildControls()
{
// Clears child controls
Controls.Clear();
// Build the control tree
CreateControlHierarchy();
ClearChildViewState();
}
protected abstract void CreateControlHierarchy();
}
TextBox control
public class LabelCheckBox : BaseCompositeControl
{
protected CheckBox _CheckBox;
public override string Text
{
get
{
EnsureChildControls();
return _CheckBox.Checked.ToString(); ;
}
set
{
EnsureChildControls();
_CheckBox.Checked = Convert.ToBoolean(value);
}
}
protected override void CreateControlHierarchy()
{
_CheckBox = new CheckBox();
Label l = new Label();
// Configure controls
l.Text = "Second Control";
// Connect to the parent
Controls.Add(l);
Controls.Add(_CheckBox);
}
}
Checkbox control
public class LabelTextBox : BaseCompositeControl
{
protected TextBox _Text;
public override string Text
{
get
{
EnsureChildControls();
return _Text.Text;
}
set
{
EnsureChildControls();
_Text.Text = value;
}
}
protected override void CreateControlHierarchy()
{
Label l = new Label();
_Text = new TextBox();
// Configure controls
l.Text = "First Control";
// Connect to the parent
Controls.Add(l);
Controls.Add(_Text);
}
}
I asked this a long time ago,
But I think this is how you should do it. Using a factory pattern for user controls.
http://weblogs.asp.net/sfeldman/archive/2007/12/17/factory-pattern-for-user-controls.aspx