Control.SetText doesn't change Text in ButtonRenderer - xamarin.forms

I'm trying to set multiple styles on the text in a Button with ButtonRenderer. On Android, styles have to be set with Control.SetText() but both the styles and the text are not applied.
It's weird that when I use the same code with LabelRenderer it works as expected.
Here is the LabelRenderer
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (Control == null || e.NewElement == null)
{
return;
}
var ce = (CustomLabel) e.NewElement;
var iconFont = Typeface.CreateFromAsset(Context.Assets, "fa-solid-900.ttf");
var spannableString = new SpannableStringBuilder();
var spannable = new SpannableString("");
spannableString.Append("Hello");
spannableString.Append(spannable, new CustomTypefaceSpan(iconFont), SpanTypes.ExclusiveInclusive);
Control.SetText(spannableString, TextView.BufferType.Spannable);
}
The result from LabelRenderer
And here is the ButtonRenderer
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (Control == null || e.NewElement == null)
{
return;
}
var ce = (AfButton) e.NewElement;
var iconFont = Typeface.CreateFromAsset(Context.Assets, "fa-solid-900.ttf");
var spannableString = new SpannableStringBuilder();
var spannable = new SpannableString(ce.IconText);
spannableString.Append(spannable, new CustomTypefaceSpan(iconFont), SpanTypes.ExclusiveInclusive);
spannableString.Append(ce.Text);
Control.SetText(spannableString, TextView.BufferType.Spannable);
}
The result from ButtonRenderer which shows the original text sets in the Text attribute.
Have anyone experienced this? Not sure if this a bug or not.
Thank you in advance for the answers.

Use the following code
var iconFont = Typeface.CreateFromAsset(Context.Assets, "xxx.ttf");
Control.Typeface = iconFont;
Update
Set SpanTypes as ExclusiveExclusive
spannableString.Append(spannable, new CustomTypefaceSpan(iconFont), SpanTypes.ExclusiveExclusive);
CustomTypefaceSpan customTypefaceSpan = new CustomTypefaceSpan(typeface);
var spannableString = new SpannableString("Hello");
spannableString.SetSpan(customTypefaceSpan, 0, spannableString.Length(), SpanTypes.ExclusiveExclusive);
var span = new SpannableString("123456");
var spp = new SpannableStringBuilder();
spp.Append(spannableString);
spp.Append(span);
Control.SetText(spp, BufferType.Spannable);

Related

Xamarin.Forms.Maps pins with expanded message window

I'm using Xamarin.Forms.Map and I want to show pins on my map with already expanded window message(without click on them). Something like screenshot. By default window message show only after I clicked on them. How can I do this?
I did a test based on this sample:sample
The thing I do is override the GetViewForAnnotation method.
I add a subview and set it's position based on pin's position.
Here is relative code:
[assembly:ExportRenderer(typeof(CustomMap),typeof(CustomMapRenderer))]
namespace My_Forms_Test3.iOS
{
public class CustomMapRenderer:MapRenderer
{
UIView customPinView;
List<CustomPin> customPins;
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
var nativeMap = Control as MKMapView;
nativeMap.GetViewForAnnotation = null;
nativeMap.CalloutAccessoryControlTapped -= OnCallourAccessoryControlTapped;
nativeMap.DidSelectAnnotationView -= OnDidSelect;
nativeMap.DidDeselectAnnotationView -= OnDidDeSelect;
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
var nativeMap = Control as MKMapView;
customPins = formsMap.CustomPins;
nativeMap.GetViewForAnnotation = GetViewForAnnotation;
nativeMap.CalloutAccessoryControlTapped += OnCallourAccessoryControlTapped;
nativeMap.DidSelectAnnotationView += OnDidSelect;
nativeMap.DidDeselectAnnotationView += OnDidDeSelect;
}
}
private void OnDidDeSelect(object sender, MKAnnotationViewEventArgs e)
{
if (!e.View.Selected)
{
customPinView.RemoveFromSuperview();
customPinView.Dispose();
customPinView = null;
}
}
private void OnDidSelect(object sender, MKAnnotationViewEventArgs e)
{
throw new NotImplementedException();
}
private void OnCallourAccessoryControlTapped(object sender, MKMapViewAccessoryTappedEventArgs e)
{
throw new NotImplementedException();
}
protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
{
MKAnnotationView annotationView = null;
if (annotation is MKUserLocation)
return null;
var customPin = GetCustomPin(annotation as MKPointAnnotation);
if (customPin == null)
{
throw new Exception("not found");
}
annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
if (annotationView == null)
{
annotationView = new CustomMKAnnotationView(annotation, customPin.Name);
annotationView.Image = UIImage.FromFile("pin.png");
annotationView.CalloutOffset = new CGPoint(0, 0);
annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("monkey.png"));
annotationView.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.DetailDisclosure);
((CustomMKAnnotationView)annotationView).Name = customPin.Name;
customPinView = new UIView();
var Label = new UILabel();
Label.Text = "Samsung";
Label.Frame=new CGRect(annotationView.GetFrame().X+35,annotationView.GetFrame().Y,100,50);
var Label2 = new UILabel();
Label2.Text = "20:20";
Label2.Frame = new CGRect(annotationView.GetFrame().X + 35, annotationView.GetFrame().Y+20, 100, 50);
customPinView.Frame= new CGRect(annotationView.GetFrame().X+40, annotationView.GetFrame().Y-20, 100, 50);
customPinView.AddSubview(Label);
customPinView.AddSubview(Label2);
Label.BaselineAdjustment = UIBaselineAdjustment.AlignBaselines;
customPinView.BackgroundColor = UIColor.White;
customPinView.Layer.CornerRadius = 5;
customPinView.Alpha = (nfloat)0.8;
customPinView.Layer.MasksToBounds = true;
annotationView.AddSubview(customPinView);
}
annotationView.CanShowCallout = true;
return annotationView;
}
CustomPin GetCustomPin(MKPointAnnotation annotation)
{
var position = new Position(annotation.Coordinate.Latitude, annotation.Coordinate.Longitude);
foreach (var pin in customPins)
{
if (pin.Position == position)
{ return pin; }
}
return null;
}}
result:

Xamarin.Forms 3.3 WKWebView inject javascript

I have followed this link Xamarin.Forms WKWebView to inject Javascript into WebView for iOS. It has worked until Xamarin.Forms 3.3.
In Xamarin.Forms 3.3, the default custom renderer for iOS can be changed from UIWebView to WKWebView. I have followed the changes in AssemblyInfo.cs. Xamarin.Forms 3.3.0. Unfortunately, the changes break the codes.
Below are the changes
//protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
//if (Control == null)
//{
userController = new WKUserContentController();
userController.RemoveAllUserScripts();
userController.RemoveScriptMessageHandler("invokeAction");
var script = new WKUserScript(new NSString(JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript(script);
userController.AddScriptMessageHandler(this, "invokeAction");
//var config = new WKWebViewConfiguration { UserContentController = userController };
webView = NativeView as WKWebView;
webView.Configuration.UserContentController = userController;
webView.WeakUIDelegate = Self;
view = Element as BibleWebView;
//webView = (WKWebView)Control;
// var cgRect = new CoreGraphics.CGRect(view.X, view.Y, view.WidthRequest, view.HeightRequest);
// webView = new WKWebView(cgRect, config)
// {
// WeakUIDelegate = Self,
// };
// SetNativeControl(webView);
//}
//if (e.OldElement != null)
//{
// userController.RemoveAllUserScripts();
// userController.RemoveScriptMessageHandler("invokeAction");
// var hybridWebView = e.OldElement as BibleWebView;
// hybridWebView.Cleanup();
// e.OldElement.ShowPopup -= OnShowPopup;
//}
//if (Control != null)
//{
// BibleWebView webview = Element as BibleWebView;
HtmlWebViewSource htmlSource = (HtmlWebViewSource)view.Source;
string html = htmlSource.Html;
webView.LoadHtmlString(new NSString(html), NSBundle.MainBundle.ResourceUrl);
view.ShowPopup += OnShowPopup;
//}
}
The old codes are commented and the new codes are uncommented. Any help will be much appreciated.
I'm using a custom renderer with Xamarin.Forms 3.3 using EvaluateJavaScript to load javascript in a loaded page.
HybridWebView is a class in my shared project that inherit from Xamarin.Forms.WebView
First option
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>
{
WKUserContentController userController;
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var formsWebView = sender as WebView;
if (formsWebView != null)
{
userController = new WKUserContentController();
var config = new WKWebViewConfiguration { UserContentController = userController };
var webView = new WKWebView(Frame, config);
SetNativeControl(webView);
Control.AllowsBackForwardNavigationGestures = true;
Control.NavigationDelegate = new CustomWebViewClient(Element);
if((formsWebView.Source as UrlWebViewSource) != null)
{
string url = System.Web.HttpUtility.UrlPathEncode((formsWebView.Source as UrlWebViewSource).Url);
Control.LoadRequest(new NSUrlRequest(new NSUrl(url)));
}
else if((formsWebView.Source as HtmlWebViewSource) != null)
{
Control.LoadHtmlString((formsWebView.Source as HtmlWebViewSource).Html, new NSUrl(""));
}
}
}
public class CustomWebViewClient : WKNavigationDelegate, INSUrlConnectionDataDelegate
{
private HybridWebView _webclient;
private WKWebView _webView;
public CustomWebViewClient(HybridWebView webclient)
{
_webclient = webclient;
}
public override void DidFinishNavigation(WKWebView webView, WKNavigation navigation)
{
string allowZoom = #"javascript:
var div = document.createElement('div');
div.setAttribute('id', 'div1');
div.innerHTML = 'Test';
document.getElementsByClassName('container')[0].appendChild(div);
div.onclick = document.getElementById('div1').onclick = function() { div.innerHTML = 'Change text'; }";
webView.EvaluateJavaScript(allowZoom, null);
_webView = webView;
}
}
}
Second option
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var formsWebView = sender as WebView;
string allowZoom = #"javascript:
var div = document.createElement('div');
div.setAttribute('id', 'div1');
div.innerHTML = 'Test';
document.getElementsByClassName('container')[0].appendChild(div);
div.onclick = document.getElementById('div1').onclick = function() { div.innerHTML = 'Change text'; }";
if (formsWebView != null)
{
userController = new WKUserContentController();
//Using WKUserScript
var script = new WKUserScript(new NSString(allowZoom), WKUserScriptInjectionTime.AtDocumentEnd, false);
userController.AddUserScript(script);
var config = new WKWebViewConfiguration { UserContentController = userController };
var webView = new WKWebView(Frame, config);
SetNativeControl(webView);
Control.AllowsBackForwardNavigationGestures = true;
Control.NavigationDelegate = new CustomWebViewClient(Element);
if((formsWebView.Source as UrlWebViewSource) != null)
{
string url = System.Web.HttpUtility.UrlPathEncode((formsWebView.Source as UrlWebViewSource).Url);
Control.LoadRequest(new NSUrlRequest(new NSUrl(url)));
}
else if((formsWebView.Source as HtmlWebViewSource) != null)
{
Control.LoadHtmlString((formsWebView.Source as HtmlWebViewSource).Html, new NSUrl(""));
}
}
}

Can't use Control.FindControl on dynamically created System.Web.UI.WebControl

Why would the following code not work? I am creating a control, adding a child control and attempting to retrieve it by id using the .FindControl method.
[Test]
public void TryToFindControl()
{
var myPanel = new Panel();
var textField = new TextBox
{
ID = "mycontrol"
};
myPanel.Controls.Add(textField);
var foundControl = myPanel.FindControl("mycontrol");
// this fails
Assert.IsNotNull(foundControl);
}
Panel has not been added to Page yet, so you cannot use FindControl. Instead, you need to find it inside Panel.Controls
[TestMethod]
public void TryToFindControl()
{
var myPanel = new Panel();
var textField = new TextBox
{
ID = "mycontrol"
};
myPanel.Controls.Add(textField);
var foundControl = myPanel.Controls
.OfType<TextBox>()
.FirstOrDefault(x => x.ID == "mycontrol");
Assert.IsNotNull(foundControl);
}
Testing with Page
FindControl works only if container is added to Page.
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
var myPanel = new Panel();
var textField = new TextBox
{
ID = "mycontrol"
};
myPanel.Controls.Add(textField);
Controls.Add(myPanel);
// foundControl is not null anymore!
var foundControl = myPanel.FindControl("mycontrol");
}
}
The control must be part of the server side Page control collection hierarchy to be found.
public void TryToFindControl()
{
var myPanel = new Panel();
// key line here
Page.Controls.Add(myPanel);
var textField = new TextBox
{
ID = "mycontrol"
};
myPanel.Controls.Add(textField);
var foundControl = myPanel.FindControl("mycontrol");
Assert.IsNotNull(foundControl);
}
First I'll start form the fact I don't know of System.UI.Control, Rather System.Web.UI.Control
Then I could not find TextField Control so I used Web TextBox instead. Please adjust your code as necessary. I also used VS Test attributes
[TestMethod()]
public void TryToFindControl()
{
var editContainer = new HtmlTableCell();
editContainer.Controls.Add(new TextBox
{
ID = "mycontrol",
});
System.Web.UI.Control foundControl = null;
foreach (System.Web.UI.Control ctrl in editContainer.Controls)
{
if (ctrl.ID == "mycontrol")
{
foundControl = ctrl;
break;
}
}
// This works
Assert.IsNotNull(foundControl);
}
Based on your exact wording, if you want to access the control you added, create an instance first as variable, so you can access it directly. Please keep in mind that I don't know what you are trying to achieve globally, so my answer(s) may not apply because of that, or there maybe be better solution.
[TestMethod()]
public void TryToFindControl()
{
var editContainer = new HtmlTableCell();
var foundControl = new TextBox
{
ID = "mycontrol"
};
editContainer.Controls.Add(foundControl);
// This works
Assert.IsNotNull(foundControl);
}

Custom GridView Server Control DataBind causes duplicate control ID's error

OK. I've long used this site as a reference, but I've now hit a wall of my own.
I am creating a custom server control which inherits from the System.Web.UI.WebControls.GridView class. It's purpose is simply to display a grid with a very defined format. It binds and loads the data fine, but trying to activate any of the paging throws an exception saying "Multiple controls with the same ID 'lblHdrText_2' were found. FindControl requires that controls have unique IDs.".
I could just throw the event out to the user and let them do the paging, but one of the goals was to have this control be able to handle its own paging, just like the GridView control already does.
I'm having the same problem for sorting and altering the page size as well. Basically anytime I call "DataBind" within the control after it has already been rendered.
Here's the code to handle those events:
protected void OnFirstPageClicked(EventArgs e)
{
if (this.FirstPageClicked != null)
this.FirstPageClicked.Invoke(this, e);
GridViewPageEventArgs pgea = new GridViewPageEventArgs(0);
this.OnPageIndexChanging(pgea);
if (pgea.Cancel)
return;
this.PageIndex = 0;
this.RefreshData();
this.OnPageIndexChanged(e);
}
protected void OnLastPageClicked(EventArgs e)
{
if (this.LastPageClicked != null)
this.LastPageClicked.Invoke(this, e);
GridViewPageEventArgs pgea = new GridViewPageEventArgs(this.PageCount - 1);
this.OnPageIndexChanging(pgea);
if (pgea.Cancel)
return;
this.PageIndex = this.PageCount - 1;
this.RefreshData();
this.OnPageIndexChanged(e);
}
protected void OnPreviousPageClicked(EventArgs e)
{
if (this.PageIndex > 0)
{
if (this.PreviousPageClicked != null)
this.PreviousPageClicked.Invoke(this, e);
GridViewPageEventArgs pgea = new GridViewPageEventArgs(this.PageIndex++);
this.OnPageIndexChanging(pgea);
if (pgea.Cancel)
return;
this.PageIndex--;
this.RefreshData();
this.OnPageIndexChanged(e);
}
}
protected void OnNextPageClicked(EventArgs e)
{
if (this.PageIndex < this.PageCount - 1)
{
if (this.NextPageClicked != null)
this.NextPageClicked.Invoke(this, e);
GridViewPageEventArgs pgea = new GridViewPageEventArgs(this.PageIndex++);
this.OnPageIndexChanging(pgea);
if (pgea.Cancel)
return;
this.PageIndex++;
this.RefreshData();
this.OnPageIndexChanged(e);
}
}
protected void OnPageSizeChanged(EventArgs e)
{
this.RefreshData();
if (this.PageSizeChanged != null)
this.PageSizeChanged.Invoke(this, e);
}
protected override void OnDataBound(EventArgs e)
{
base.OnDataBound(e);
}
private void RefreshData()
{
this.DataBind();
}
private void imgPg_OnCommand(object sender, CommandEventArgs e)
{
switch (e.CommandName)
{
case "FirstPage":
this.OnFirstPageClicked(EventArgs.Empty);
break;
case "LastPage":
this.OnLastPageClicked(EventArgs.Empty);
break;
case "PrevPage":
this.OnPreviousPageClicked(EventArgs.Empty);
break;
case "NextPage":
this.OnNextPageClicked(EventArgs.Empty);
break;
}
}
private void drpPageSz_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList drpPgSz = (sender as DropDownList);
if (drpPgSz != null)
{
this.PageSize = int.Parse(drpPgSz.SelectedValue);
this.OnPageSizeChanged(e);
}
else
throw new Exception("Unable to determine page size: cannot cast sender as DropDownList.");
}
The actual event handlers are at the bottom. The "RefreshData" method is just there because I was experimenting with different ways of clearing the controls from the grid before I called "DataBind". So far, everything I've tried results in the entire grid not rendering after postback.
I am doing quite a bit with the Render and CreateChildControls, but the header generation itself is completely internal to the System.Web.UI.WebControls.GridView control. Here's my rendering code, if it helps at all:
protected override void OnPreRender(EventArgs e)
{
Control link = this.Page.Header.FindControl("CustomGridViewCss");
if (link == null)
{
System.Web.UI.HtmlControls.HtmlLink newLink = new System.Web.UI.HtmlControls.HtmlLink();
newLink.ID = "CustomGridViewCss";
newLink.Attributes.Add("href", this.Page.ClientScript.GetWebResourceUrl(typeof(ITCWebToolkit.Web.UI.Controls.GridView), "ITCWebToolkit.Web.UI.Controls.style.CustomGridView.css"));
newLink.Attributes.Add("type", "text/css");
newLink.Attributes.Add("rel", "stylesheet");
this.Page.Header.Controls.Add(newLink);
}
base.OnPreRender(e);
this.EnsureChildControls();
}
protected override void Render(HtmlTextWriter writer)
{
if (this._imgFPg != null)
this.Page.ClientScript.RegisterForEventValidation(this._imgFPg.UniqueID);
if (this._imgPrevPg != null)
this.Page.ClientScript.RegisterForEventValidation(this._imgPrevPg.UniqueID);
if (this._imgNextPg != null)
this.Page.ClientScript.RegisterForEventValidation(this._imgNextPg.UniqueID);
if (this._imgLastPg != null)
this.Page.ClientScript.RegisterForEventValidation(this._imgLastPg.UniqueID);
if (this._drpPageSz != null)
this.Page.ClientScript.RegisterForEventValidation(this._drpPageSz.UniqueID);
if (this.HeaderRow != null)
for (int i = 1; i < this.HeaderRow.Cells.Count - 2; i++)
if (i < this.Columns.Count && this.Columns[i] is SortableField && ((this.Columns[i] as SortableField).ShowSort))
{
ImageButton img = (this.HeaderRow.Cells[i].FindControl("imgSort_" + i.ToString()) as ImageButton);
if (img != null)
this.Page.ClientScript.RegisterForEventValidation(img.UniqueID);
}
base.Render(writer);
}
protected override Table CreateChildTable()
{
this.PagerSettings.Visible = false;
this.GridLines = GridLines.None;
Table tbl = base.CreateChildTable();
tbl.Attributes.Add("name", this.UniqueID);
return tbl;
}
protected override int CreateChildControls(System.Collections.IEnumerable dataSource, bool dataBinding)
{
this.GridLines = GridLines.None;
int iCount = base.CreateChildControls(dataSource, dataBinding);
// Modify footer row
System.Web.UI.WebControls.GridViewRow ftr = this.FooterRow;
// NOTE: We're modifying the footer first, because we're looking at the
// total number of rows in the header for the ColSpan property we
// use in the footer and we want the row count *before* we modify
// the header.
ftr.Cells.Clear();
this.BuildFooter(this.FooterRow);
// Modify Header Row
System.Web.UI.WebControls.GridViewRow hdr = this.HeaderRow;
hdr.CssClass = "GridViewHeader";
for (int c = 0; c < hdr.Cells.Count; c++)
{
hdr.Cells[c].CssClass = "GridViewHeaderTC";
if (c > 0)
hdr.Cells[c].Style.Add("border-left", "solid 1px #ccccd3");
if (c < this.Columns.Count && this.Columns[c] is SortableField && ((this.Columns[c] as SortableField).ShowSort))
{
hdr.Cells[c].Controls.Clear();
Label lblHdrText = new Label();
lblHdrText.ID = "lblHdrText_" + c.ToString();
lblHdrText.Text = hdr.Cells[c].Text;
hdr.Cells[c].Controls.Add(lblHdrText);
ImageButton imgSort = new ImageButton();
imgSort.ID = "imgSort_" + c.ToString();
imgSort.CssClass = "GridViewHeaderSort";
imgSort.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(typeof(ITCWebToolkit.Web.UI.Controls.GridView), "ITCWebToolkit.Web.UI.Controls.images.gridView.Sort.png");
imgSort.AlternateText = "";
imgSort.CommandArgument = (this.Columns[c] as BoundField).DataField;
imgSort.CommandName = "Sort";
imgSort.Command += new CommandEventHandler(this.imgSort_OnCommand);
hdr.Cells[c].Controls.Add(imgSort);
imgSort.Attributes.Add("name", imgSort.UniqueID);
}
}
TableCell tdTL = new TableCell();
tdTL.Style.Add(HtmlTextWriterStyle.Width, "6px");
tdTL.CssClass = "GridViewHeaderTL";
hdr.Cells.AddAt(0, tdTL);
TableCell tdTR = new TableCell();
tdTR.Style.Add(HtmlTextWriterStyle.Width, "6px");
tdTR.Style.Add("border-left", "1px solid #ccccd3;");
tdTR.CssClass = "GridViewHeaderTR";
hdr.Cells.Add(tdTR);
// Modify individual rows
for (int i = 0; i < this.Rows.Count; i++)
{
System.Web.UI.WebControls.GridViewRow tr = this.Rows[i];
tr.CssClass = (i % 2 == 0) ? "GridViewLineAlt" : "GridViewLine";
for (int c = 0; c < tr.Cells.Count - 1; c++)
tr.Cells[c].Style.Add("border-right", "solid 1px #ccccd3");
TableCell tdL = new TableCell();
tdL.CssClass = "GridViewLineLeft";
tr.Cells.AddAt(0, tdL);
TableCell tdR = new TableCell();
tdR.CssClass = "GridViewLineRight";
tr.Cells.Add(tdR);
}
return iCount;
}
protected void BuildFooter(GridViewRow tr)
{
TableCell tdBL = new TableCell();
tdBL.Style.Add(HtmlTextWriterStyle.Width, "6px");
tdBL.CssClass = "GridViewFooterBL";
tr.Cells.Add(tdBL);
int colCount = this.HeaderRow.Cells.Count;
TableCell td = new TableCell();
td.ID = "tdFooterControls";
td.CssClass = "GridViewFooterBC";
td.ColumnSpan = colCount;
this._spanPgBtns = new Label();
this._spanPgBtns.ID = "spanPgButtons";
this._spanPgBtns.Style.Add("float", "right");
this._spanPgBtns.Style.Add("margin-right", "20px");
this._imgFPg = new ImageButton();
this._imgFPg.ID = "imgFPg";
this._imgFPg.CssClass = "FirstPg";
this._imgFPg.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(typeof(ITCWebToolkit.Web.UI.Controls.GridView), "ITCWebToolkit.Web.UI.Controls.images.gridView.FstPg.png");
this._imgFPg.ImageAlign = ImageAlign.Middle;
this._imgFPg.CommandName = "FirstPage";
this._imgFPg.Command += new CommandEventHandler(this.imgPg_OnCommand);
this._spanPgBtns.Controls.Add(this._imgFPg);
this._imgPrevPg = new ImageButton();
this._imgPrevPg.ID = "imgPrevPg";
this._imgPrevPg.CssClass = "PrevPg";
this._imgPrevPg.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(typeof(ITCWebToolkit.Web.UI.Controls.GridView), "ITCWebToolkit.Web.UI.Controls.images.gridView.PrevPg.png");
this._imgPrevPg.ImageAlign = ImageAlign.Middle;
this._imgPrevPg.CommandName = "PrevPage";
this._imgPrevPg.Command += new CommandEventHandler(this.imgPg_OnCommand);
this._spanPgBtns.Controls.Add(this._imgPrevPg);
Label lblPageNum = new Label();
lblPageNum.ID = "lblPageNum";
lblPageNum.Width = new Unit("50px");
lblPageNum.Text = string.Format("{0} / {1}", this.PageIndex + 1, this.PageCount);
lblPageNum.Style.Add(HtmlTextWriterStyle.TextAlign, "center");
this._spanPgBtns.Controls.Add(lblPageNum);
this._imgNextPg = new ImageButton();
this._imgNextPg.ID = "imgNextPg";
this._imgNextPg.CssClass = "NextPg";
this._imgNextPg.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(typeof(ITCWebToolkit.Web.UI.Controls.GridView), "ITCWebToolkit.Web.UI.Controls.images.gridView.NextPg.png");
this._imgNextPg.ImageAlign = ImageAlign.Middle;
this._imgNextPg.CommandName = "NextPage";
this._imgNextPg.Command += new CommandEventHandler(this.imgPg_OnCommand);
this._spanPgBtns.Controls.Add(this._imgNextPg);
this._imgLastPg = new ImageButton();
this._imgLastPg.ID = "imgLastPg";
this._imgLastPg.CssClass = "LastPg";
this._imgLastPg.ImageUrl = this.Page.ClientScript.GetWebResourceUrl(typeof(ITCWebToolkit.Web.UI.Controls.GridView), "ITCWebToolkit.Web.UI.Controls.images.gridView.LstPg.png");
this._imgLastPg.ImageAlign = ImageAlign.Middle;
this._imgLastPg.CommandName = "LastPage";
this._imgLastPg.Command += new CommandEventHandler(this.imgPg_OnCommand);
this._spanPgBtns.Controls.Add(this._imgLastPg);
td.Controls.Add(this._spanPgBtns);
Label spanPageSz = new Label();
spanPageSz.ID = "spanPageSz";
spanPageSz.Style.Add("margin-left", "20px");
this._drpPageSz = new DropDownList();
this._drpPageSz.ID = "drpPageSzSelect";
this._drpPageSz.AutoPostBack = true;
this._drpPageSz.SelectedIndexChanged += new EventHandler(drpPageSz_SelectedIndexChanged);
this._drpPageSz.Items.Add(new ListItem("10", "10"));
this._drpPageSz.Items.Add(new ListItem("25", "25"));
this._drpPageSz.Items.Add(new ListItem("50", "50"));
this._drpPageSz.Items.Add(new ListItem("100", "100"));
spanPageSz.Controls.Add(this._drpPageSz);
td.Controls.Add(spanPageSz);
Label lblRecVis = new Label();
lblRecVis.ID = "lblRecordsCount";
lblRecVis.Style.Add("margin-left", "20px");
lblRecVis.Text = string.Format("Displaying {0} of {1} records.", Math.Min(this.PageSize, this.Rows.Count - (this.PageIndex * this.PageSize)), this.Rows.Count);
lblRecVis.Text = "Total Record Display";
td.Controls.Add(lblRecVis);
tr.Cells.Add(td);
TableCell tdBR = new TableCell();
tdBR.Style.Add(HtmlTextWriterStyle.Width, "6px");
tdBR.CssClass = "GridViewFooterBR";
tr.Cells.Add(tdBR);
this._imgFPg.Attributes.Add("name", this._imgFPg.UniqueID);
this._imgPrevPg.Attributes.Add("name", this._imgPrevPg.UniqueID);
this._imgNextPg.Attributes.Add("name", this._imgNextPg.UniqueID);
this._imgLastPg.Attributes.Add("name", this._imgLastPg.UniqueID);
this._drpPageSz.Attributes.Add("name", this._drpPageSz.UniqueID);
}
I'm only about 6/10 on custom server controls, so I'm sure there's at least one thing I'm doing wrong here :)
Thanks in advance for any help!
OK. I finally found a reference and answered my own question. The trick is in overriding the "PerformSelect" method and handling DataSource vs DataSourceID there.
Details on how to do this can be found on this MSDN page:
http://msdn.microsoft.com/en-us/library/ms366539(v=vs.90).aspx
Look for the section titled "Initiate Data Retrieval" a little over half-way down.

Type Casting Issue with List View OnItemDataBound Event

On Page Load Event I am trying to do
protected void Page_Load(object sender, EventArgs e)
{
XmlReader reader = XmlReader.Create(FeedUrl);
SyndicationFeed feed = SyndicationFeed.Load(reader);
lstViewNewsFeeds.DataSource = feed.Items;
lstViewNewsFeeds.DataBind();
}
protected void lstViewNewsFeeds_ItemDataBound(object sender, ListViewItemEventArgs e)
{
try
{
// Instantiate listview control object.
ListViewDataItem lvDataItem = (ListViewDataItem)e.Item;
at this line given exception
**DataRowView drvItem = (DataRowView)lvDataItem.DataItem;**
//Make sure that data item is binding with listview.
if (lvDataItem.ItemType == ListViewItemType.DataItem)
{
SyndicationItem item = e.Item.DataItem as SyndicationItem;
LinkButton linkButtonTitle = (LinkButton)e.Item.FindControl("lbNewsTitle");
Panel panelNewsDescContent = (Panel)e.Item.FindControl("panelNewsDescription");
// Make sure that linkButtonTile is referenced.
if (linkButtonTitle != null)
{
// linkButtonTitle.Text = Convert.ToString(item.Title);
linkButtonTitle.Text = Convert.ToString(drvItem["Title"]);
}
// Make sure that panel object is referenced.
if (panelNewsDescContent != null)
{
Label lblBox = new Label();
// lblBox.Text = Convert.ToString(item.Summary);
panelNewsDescContent.Controls.Add(lblBox);
}
//Label l = e.Row.FindControl("Label1") as Label;
//l.Text = item.Title.Text;
//HyperLink hl = e.Row.FindControl("HyperLink1") as HyperLink;
//hl.Text = item.Title.Text;
//hl.NavigateUrl = item.Links[0].Uri.AbsoluteUri;
}
}
catch(Exception ee)
{
Response.Write(ee.Message);
}
Giving Error:
'System.Data.DataRowView'.Unable to cast object of type
'System.ServiceModel.Syndication.SyndicationItem' to type
'System.Data.DataRowView'.Unable to cast object of type
I am not able to understand how i remove this error. Please help me here.
SyndicationFeed.Items Property returns an IEnumerable<SyndicationItem>, so you should cast it to SyndicationItem instead.
SyndicationItem item = (SyndicationItem)lvDataItem.DataItem;
i have tried this works fine.
SyndicationItem item = e.Item.DataItem as SyndicationItem;
protected void lstViewNewsFeeds_ItemDataBound(object sender, ListViewItemEventArgs e)
{
try
{
// Instantiate listview control object.
ListViewDataItem lvDataItem = (ListViewDataItem)e.Item;
//DataRowView drvItem = (DataRowView)lvDataItem.DataItem;
//SyndicationItem item = (SyndicationItem)lvDataItem.DataItem;
//Make sure that data item is binding with listview.
if (lvDataItem.ItemType == ListViewItemType.DataItem)
{
SyndicationItem item = e.Item.DataItem as SyndicationItem;
LinkButton linkButtonTitle = (LinkButton)e.Item.FindControl("lbNewsTitle");
Panel panelNewsDescContent = (Panel)e.Item.FindControl("panelNewsDescription");
// Make sure that linkButtonTile is referenced.
if (linkButtonTitle != null)
{
// linkButtonTitle.Text = Convert.ToString(item.Title);
linkButtonTitle.Text = Convert.ToString(item.Title.Text);
}
// Make sure that panel object is referenced.
if (panelNewsDescContent != null)
{
Label lblBox = new Label();
lblBox.Text = Convert.ToString(item.Summary);
panelNewsDescContent.Controls.Add(lblBox);
}
//Label l = e.Row.FindControl("Label1") as Label;
//l.Text = item.Title.Text;
//HyperLink hl = e.Row.FindControl("HyperLink1") as HyperLink;
//hl.Text = item.Title.Text;
//hl.NavigateUrl = item.Links[0].Uri.AbsoluteUri;
}
}
catch(Exception ee)
{
Response.Write(ee.Message);
}
}
By The way thanks all of you for help.
Try this:
protected void lstViewNewsFeeds_ItemDataBound(object sender, ListViewItemEventArgs e)
{
try
{
//Make sure that data item is binding with listview.
if (lvDataItem.ItemType == ListViewItemType.DataItem)
{
SyndicationItem item = e.Item.DataItem as SyndicationItem;
LinkButton linkButtonTitle = (LinkButton)e.Item.FindControl("lbNewsTitle");
Panel panelNewsDescContent = (Panel)e.Item.FindControl("panelNewsDescription");
// Make sure that linkButtonTile is referenced.
if (linkButtonTitle != null)
{
linkButtonTitle.Text = Convert.ToString(item.Title);
}
// Make sure that panel object is referenced.
if (panelNewsDescContent != null)
{
Label lblBox = new Label();
lblBox.Text = Convert.ToString(item.Summary);
panelNewsDescContent.Controls.Add(lblBox);
}
Label l = e.Row.FindControl("Label1") as Label;
l.Text = item.Title.Text;
HyperLink hl = e.Row.FindControl("HyperLink1") as HyperLink;
hl.Text = item.Title.Text;
hl.NavigateUrl = item.Links[0].Uri.AbsoluteUri;
}
}
catch(Exception ee)
{
Response.Write(ee.Message);
}
}

Resources