If I pass the derived class testA a PlaceHolder that contains a Hyperlink, with a url that starts with
a tilde, it resolves it correctly.
However, when I pass testB
(identical apart from it inherits from
System.Web.UI.UserControl) the same PlaceHolder It
renders it literally (doesn't
transform / resolve the '~')
Any ideas?
public class testA : System.Web.UI.Control
{
public System.Web.UI.WebControls.PlaceHolder plc { get; set; }
protected override void OnLoad(EventArgs e)
{
if (plc != null)
this.Controls.Add(plc);
base.OnLoad(e);
}
}
public class testB : System.Web.UI.UserControl
{
public System.Web.UI.WebControls.PlaceHolder plc { get; set; }
protected override void OnLoad(EventArgs e)
{
if (plc != null)
this.Controls.Add(plc);
base.OnLoad(e);
}
}
This is ASP.NET
When you inherit from System.Web.UI.UserControl and do not associate your control with an ascx file then your control TemplateSourceVirtualDirectory will not be set, this is required by the ResolveClientUrl method - if its null or empty the url will be returned AS IS.
To solve your problem, just set AppRelativeTemplateSourceDirectory :
public class testB : System.Web.UI.UserControl
{
public System.Web.UI.WebControls.PlaceHolder plc { get; set; }
protected override void OnLoad(EventArgs e)
{
if (plc != null)
{
this.AppRelativeTemplateSourceDirectory =
plc.AppRelativeTemplateSourceDirectory;
this.Controls.Add(plc);
}
base.OnLoad(e);
}
}
A UserControl is normally associated with an ascx file that defines its markup. Such controls should be instantiated using TemplateControl.LoadControl() before they're added to the page, in order to perform event catch-up.
I suspect that event catch-up does not take place since you don't call LoadControl(), so the Hyperlink's NavigateUrl never gets a chance to be properly resolved.
Related
I've custom renderer in Xamarin and I wonder how to dynamically update its value.
Here is my control in the main class:
public class MainControl : View
{
public double A
{
get;
set;
}
}
Here is my custom renderer, defined in Android:
[assembly: Xamarin.Forms.ExportRenderer(typeof(MainApplication.MainControl), typeof(MainApplication.Droid.CustomRenderer))]
namespace MainApplication.Droid
{
public class CustomRenderer : ViewRenderer<MainControl,
MainApplication.Droid.ControlAndroid>
{
private ControlAndroid control;
public CustomRenderer(Context context) : base(context)
{
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
}
protected override void OnElementChanged(ElementChangedEventArgs<MainControl> e)
{
base.OnElementChanged(e);
if (Control == null)
{
control = new ControlAndroid(Context);
SetNativeControl(control);
}
}
}
}
The method OnElementChanged does only update when creating the object. OnElementPropertyChanged are not trigged.
I expected that something should be trigged when changing the value of the property A from the main class.
I found the answer by my own. I figured out that I needed a bindable property (connected to my regular property "A") in order to get a call on OnElementPropertyChanged.
I am developing Windows Phone 8.1 app with MVVM.
I have base view model class which contains Navigation Service as below:
public abstract class BaseViewModel : INotifyPropertyChanged
{
protected readonly INavigationService NavigationService;
//....
}
There is my navigation service class:
public class NavigationService : INavigationService
{
public void Navigate(Type destinationPage)
{
((Frame)Window.Current.Content).Navigate(destinationPage);
}
public void Navigate(Type desitnationPage, object parameter)
{
((Frame)Window.Current.Content).Navigate(desitnationPage, parameter);
}
public void GoBack()
{
((Frame)Window.Current.Content).GoBack();
}
}
Everything is working fine when I am binding commands from XAML. There is problem when I want to override BackButton. I have also created base page model which also contains NavigationService. Each page has an overridde pf BackPressed as below:
public class BasePage : Page
{
protected INavigationService NavigationService => ComponentManager.GetInstance<INavigationService>();
public BasePage()
{
//...
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
}
protected virtual void HardwareButtons_BackPressed(object sender, BackPressedEventArgs e)
{
//Frame.Navigate(typeof(MainPage));
(this.DataContext as BaseViewModel)?.Back.Execute(sender);
}
}
As you see in HardwareButtons_BackPressed method I've tried to make it in to ways but none is workings. Every time I press back button application crashes without any error.
I don't think the app is crashing, it's just exiting because that is the default behaviour of the back button.
What you need to do is flag that you've handled the back button by adding this line of code in your BackPressed event handler:
e.Handled = true;
My WebForms project uses an NHibernate class library as an OR mapper to our Oracle databases. The NHibernate library has been fully tested and is working without any issues.
Global.asax.cs:
void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
var cnnConfig = ""; //contains connection string information for NH
NHibernateClassLibrary.init(cnnConfig); //initializes NHibernate
var profileType = typeof(AutoMapper.Profile);
// Get an instance of each Profile in the executing assembly.
var profiles = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => profileType.IsAssignableFrom(t)
&& t.GetConstructor(Type.EmptyTypes) != null)
.Select(Activator.CreateInstance)
.Cast<Profile>();
// Initialize AutoMapper with each instance of the profiles found.
Mapper.Initialize(a => profiles.ForEach(a.AddProfile)); //ForEach is an extension method
}
ExtensionMethods.cs:
public static class ExtensionMethods
{
public static void ForEach<T>(this IEnumerable<T> enumerable,
Action<T> action)
{
foreach (T item in enumerable) { action(item); }
}
}
SampleProfile.cs:
namespace MyProjectName.AutomapperProfiles
{
public class EntityOneProfile : Profile
{
protected override void Configure()
{
base.Configure();
Mapper.CreateMap<NHibernateClassLibrary.Entities.EntityOne, EntityOnePoco>();
}
}
}
EntityOne.cs:
namespace NHibernateClassLibrary.Entities
{
public class EntityOne
{
public virtual string PropertyOne { get; set; }
public virtual string PropertyTwo { get; set; }
public virtual string PropertyThree { get; set; }
}
}
EntityOnePoco.cs:
namespace MyProjectName.GridEntities
{
public class EntityOnePoco
{
public string PropertyOne { get; set; }
public string PropertyTwo { get; set; }
public string PropertyThree { get; set; }
}
}
MyPage.aspx.cs:
namespace MyProjectName
{
public partial class MyPage : System.Web.UI.Page
{
//This gets us access to the NHibernate Class Library
IDATABASE DataBase = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDATABASE>();
protected void Page_Load(object sender, EventArgs e)
{
var EntityOneRaw = DataBase.EntityOne.ToList();
var EntityOneObjects = EntityOneRaw.Select(q => AutoMapper.Mapper.Map<NHibernateClassLibrary.Entities.EntityOne, EntityOnePoco>(q)).ToList();
GridViewObject.DataSource = new BindingList<EntityOnePoco>(EntityOneObjects);
GridViewObject.DataBind();
}
protected void ButtonOne_Click(object sender, EventArgs e)
{
var Item = DataBase.EntityOne.First();
Item.PropertyTwo = "New Value";
DataBase.SaveChanges(); //NHibernate call to commit
}
}
}
MyPage.aspx:
<!--Other lines truncated-->
<dx:ASPxGridView ID="GridViewObject" runat="server" KeyFieldName="PropertyOne">
</dx:ASPxGridView>
<asp:Button ID="ButtonOne" runat="server" Text="Take Action" OnClick="ButtonOne_Click" />
The page_load method works fine. The grid will load with the database's current values, with the first entry's "PropertyTwo" equal to "Old Value" for example. If I press ButtonOne, the ButtonOne_Click method will fire and update the first entry in the EntityOne table appropriately. I've confirmed this directly in Oracle. Further, a breakpoint set right after this action completes shows that the NHibernateClassLibrary is appropriately fetching the new property. However, the GridView is still displaying "Old Value" until I stop IIS/Debugging and restart.
My first instinct is that caching is enabled somewhere, but I've confirmed NHibernate is not caching the old value. If EntityOne from the database is up to date, how do I force the AutoMapped EntityOnePoco to update at the same time? Am I missing something easy here?
The solution I found was to call DataBase.Clear(), essentially clearing the first-level NHibernate cache right before populating the EntityOneRaw object, as in the following example. My use-case benefits from first-level caching, so in my actual code, I only call the Clear() method as necessary.
namespace MyProjectName
{
public partial class MyPage : System.Web.UI.Page
{
//This gets us access to the NHibernate Class Library
IDATABASE DataBase = Microsoft.Practices.ServiceLocation.ServiceLocator.Current.GetInstance<IDATABASE>();
protected void Page_Load(object sender, EventArgs e)
{
DataBase.Clear(); //clear the first-level cache in NHibernaet
var EntityOneRaw = DataBase.EntityOne.ToList();
var EntityOneObjects = EntityOneRaw.Select(q => AutoMapper.Mapper.Map<NHibernateClassLibrary.Entities.EntityOne, EntityOnePoco>(q)).ToList();
GridViewObject.DataSource = new BindingList<EntityOnePoco>(EntityOneObjects);
GridViewObject.DataBind();
}
protected void ButtonOne_Click(object sender, EventArgs e)
{
var Item = DataBase.EntityOne.First();
Item.PropertyTwo = "New Value";
DataBase.SaveChanges(); //NHibernate call to commit
}
}
}
I need to set data for a custom control in my HTML file but I'm experiencing problems with ParseChildren property which doesn't work and my code raises a "Parser Error" for "Object not set to an instance of an object".
Here is my code behind:
namespace UserControls
{
[ParseChildren(true)]
public partial class MainVisit : UserControl
{
[PersistenceMode(PersistenceMode.InnerProperty)]
public MyCollection MyList { get; private set; }
public MainVisit()
{
this.MyList = new MyCollection();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
this.MyList = new MyCollection();
}
}
public class MyCollection : List<SecondaryVisit> { }
public class SecondaryVisit
{
public string Name { get; set; }
public SecondaryVisit() { }
}
}
And this is the HTML file
<%# Register TagPrefix="mscuc" TagName="MainVisitForm" Src="~/UserControls/MainVisit.ascx" %>
<mscuc:MainVisitForm id="MainVisitForm" runat="server">
<VisitList>
<mscuc:SecondaryVisit Name="visit_name" />
</VisitList>
</mscuc:MainVisitForm>
So when I compile and try to execute this code an exception is raised for "Object not set to an instance of an object" at line
Any idea?
this is what i had research in this few day, but i still cannot show the controls in design time... its keep show Type " System.Web.UI.UserControl does not have a public property name. The control is not showing while i have a inner property
Example .aspx code:
<XF:XFButton ID="XFButton1" runat="server" >
<Button1 ClientSideEvents-Click = "function(s,e){ApplyJavascript();}"></Button1>
</XF:XFButton>
Example behind .ascx code:
namespace XESControlsTestApp.WebControl
{
[PersistenceMode(PersistenceMode.InnerProperty)]
[ParseChildren(true)]
[Browsable(true)]
public class ContentContainer : Control, INamingContainer {
private ITemplate _content;
public ITemplate ContentTemplate
{
get { return this._content; }
set { this._content = value; }
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (this._content != null)
{
ContentContainer container = new ContentContainer();
this._content.InstantiateIn(container);
this._content.InstantiateIn(this);
}
}
}