Extend DropDownList to add ListSearchExtender - extend

I want to extend DropDownList to add ListSearchExtender.
Using the code below, the control works well in runtime but in design time it give me this error:
SearchDropDownList - DdlTest There was an error rendering the
control. Page cannot be null. Please ensure that this operation is
being performed in the context of an ASP.NET request.
I'd like to understand the cause of this error.
[ToolboxData("<{0}:SearchDropDownList runat=\"server\"></{0}:SearchDropDownList>")]
public class SearchDropDownList : DropDownList
{
private ListSearchExtender listSearchExt = new ListSearchExtender();
protected override void OnInit(EventArgs e)
{
ReloadSettings();
}
protected override void Render(HtmlTextWriter w)
{
base.Render(w);
listSearchExt.RenderControl(w);
}
public void ReloadSettings()
{
listSearchExt.TargetControlID = this.ID;
listSearchExt.ID = this.ID + "_CalendarExtender";
if (Controls.Count > 0)
{
foreach (Control item in Controls)
{
if (item.ID == listSearchExt.ID)
{
Controls.Remove(item);
}
}
}
Controls.Add(listSearchExt);
}
}

i got it by simple way i am not sure if it will make problem in future but for now it work well
protected override void Render(HtmlTextWriter w)
{
base.Render(w);
if (!this.DesignMode)
{
listSearchExt.RenderControl(w);
}
}

Related

Revit Synchronization event

Starting with this...
https://github.com/jeremytammik/RevitLookup/blob/master/CS/EventTrack/Events/ApplicationEvents.cs
I'm trying to add an event listener for a synchronization event. the code below throws an error stating that the m_app is null. Can i not subscribe to this event while Revit is starting up?
I was able to do this before with application.ViewActivated += ..... Im wondering if this has something to do with DB vs UI driven events and when they are allowed to be subscribed to? I just don't know.
namespace RevitModelHealth
{
public class checkHealth : IExternalApplication
{
// Document doc;
static public Autodesk.Revit.ApplicationServices.Application m_app = null;
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
return Result.Succeeded;
}
void m_app_DocumentSavingToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizingWithCentralEventArgs e)
{
MessageBox.Show("asd","asd");
}
}
}
Here is updated code reflecting my response to the first answer. The message box opens when the document is loaded. No errors are thrown when I try to initialize the synchronization event handlers, however, neither of the message boxes open before or after a synchronization event.
public class checkHealth : IExternalApplication
{
// Document doc;
static public Autodesk.Revit.ApplicationServices.Application m_app;
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
application.ControlledApplication.DocumentOpened += new EventHandler<DocumentOpenedEventArgs>(app_DocOpened);
return Result.Succeeded;
}
public void app_DocOpened(object sender, DocumentOpenedEventArgs args)
{
MessageBox.Show("asd","asd");
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
m_app.DocumentSynchronizedWithCentral += new EventHandler<Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs>(m_app_DocumentSavedToCentral);
}
void m_app_DocumentSavingToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizingWithCentralEventArgs e)
{
MessageBox.Show("sync", "sync");
}
void m_app_DocumentSavedToCentral(object sender, Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs e)
{
MessageBox.Show("Doone", "Done");
}
}
this worked.... Thanks largely in part to the SDK sample project EventsMonitor
namespace RevitModelHealth
{
public class checkHealth : IExternalApplication
{
public Result OnShutdown(UIControlledApplication application)
{
return Result.Succeeded;
}
public Result OnStartup(UIControlledApplication application)
{
application.ControlledApplication.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(app_syncStart);
application.ControlledApplication.DocumentSynchronizedWithCentral += new EventHandler<DocumentSynchronizedWithCentralEventArgs>(app_syncOver);
return Result.Succeeded;
}
public void app_syncStart(object o ,DocumentSynchronizingWithCentralEventArgs args)
{
MessageBox.Show("","Stasrting");
}
public void app_syncOver(object o,DocumentSynchronizedWithCentralEventArgs args)
{
MessageBox.Show("", "Over");
}
}
}
Try
application.ControlledApplication.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral)
in your OnStartup() method.
The call is failing because instance member m_app is initialized to null.
The UIApplication.ControlledApplication object that raises the DocumentSynchronizingWithCentralEventArgs is being accessible from the parameter to OnStartup.
You can try this:
public void app_DocOpened(object sender, DocumentOpenedEventArgs args)
{
MessageBox.Show("asd","asd");
Autodesk.Revit.ApplicationServices.Application m_app = args.Document.Application;
m_app.DocumentSynchronizingWithCentral += new EventHandler<DocumentSynchronizingWithCentralEventArgs>(m_app_DocumentSavingToCentral);
m_app.DocumentSynchronizedWithCentral += new EventHandler<Autodesk.Revit.DB.Events.DocumentSynchronizedWithCentralEventArgs>(m_app_DocumentSavedToCentral);
}

PRISM Xamarin - Working with tabbed pages (IActiveAware)

I have tab pages implementing different views, but I cannot initialize each of the tabs when navigating.
<TabbedPage.Children>
<tabPages:Page1/>
<tabPages:Page2/>
<tabPages:Page3/>
</TabbedPage.Children>
So what I did was to use IActiveAware as prism documentation suggested to know which tab page is currently active. So I have this class:
public abstract class TabbedChildViewModelBase : BaseViewModel, IActiveAware, INavigationAware, IDestructible
protected bool IsInitalized { get; set; }
private bool _IsActive;
public bool IsActive
{
get
{
return _IsActive;
}
set
{
SetProperty(ref _IsActive, value, RaiseIsActiveChanged);
}
}
public event EventHandler IsActiveChanged;
public virtual void OnNavigatingTo(NavigationParameters parameters)
{
}
protected virtual void RaiseIsActiveChanged()
{
IsActiveChanged?.Invoke(this, EventArgs.Empty);
}
public virtual void Destroy()
{
}
}
So each child view models inherits the child view model base:
public class Page1 : TabbedChildViewModelBase
{
public CurrentSeaServiceViewModel()
{
IsActiveChanged += HandleIsActiveTrue;
IsActiveChanged += HandleIsActiveFalse;
}
private void HandleIsActiveTrue(object sender, EventArgs args)
{
if (IsActive == false)
{
TestLabelOnly = "Test";
}
// Handle Logic Here
}
private void HandleIsActiveFalse(object sender, EventArgs args)
{
if (IsActive == true) return;
// Handle Logic Here
}
public override void Destroy()
{
IsActiveChanged -= HandleIsActiveTrue;
IsActiveChanged -= HandleIsActiveFalse;
}
}
The problem is, the child vm isn't initializing. Is there something needed in order to implement IActiveAware properly nor launching the IsActive property
I still used IActiveAware unfortunately, to make the childtabbedviewmodel work you need to bind the page to its own view model.
So here's what I did:
<TabbedPage.Children>
<views:ChildPage1>
<views:ChildPage1.BindingContext>
<viewModels:ChildPage1ViewModel/>
</views:ChildPage1.BindingContext>
</views:ChildPage1>
<views:ChildPage2>
<views:ChildPage2.BindingContext>
<viewModels:ChildPage2ViewModel/>
</views:ChildPage2.BindingContext>
</views:ChildPage2>
</TabbedPage.Children>
I used the property BindingContext of my views and
using IActiveAware I would also know what tab is currently active. Hope anyone helps this who finds trouble binding the child pages of a tab.

Xamarin MVVM push user data to viewmodel

like the title says I want to give through the user information to my viewmodel, but the problem is that the viewmodel is registered as a dependency and I am binding its content to the xaml page itself. How do I send the user information to the viewmodel itself?
Thank you!
Xaml.cs part:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Calendar : ContentPage
{
public Calendar(User user)
{
InitializeComponent();
FileImageSource image = new FileImageSource
{
File = "calendar.png"
};
Icon = image;// push user information to the ICalendarViewModel
BindingContext = AppContainer.Container.Resolve<ICalendarViewModel>();
}
}
Interface:
public interface ICalendarViewModel : INotifyPropertyChanged
{
}
Bootstrap part registering dependencies:
public class Bootstrap
{
public IContainer CreateContainer()
{
var containerBuilder = new ContainerBuilder();
RegisterDependencies(containerBuilder);
return containerBuilder.Build();
}
protected virtual void RegisterDependencies(ContainerBuilder builder)
{
builder.RegisterType<CalendarViewModel>()
.As<ICalendarViewModel>()
.SingleInstance();
}
}
CalendarViewModel: I do not know if this will help
public class CalendarViewModel : ViewModelBase, ICalendarViewModel
{
public event PropertyChangedEventHandler PropertyChanged;
public string ErrorMessage { get; set; }
private CourseInformation _information;
private ICourseInformationRepository _repository;
public CalendarViewModel()
{
_repository = new CourseInformationRepository();
LoadData();
}
private ObservableCollection<CourseInformation> _courses;
public ObservableCollection<CourseInformation> Courses
{
get
{
return _courses;
}
set
{
_courses = value;
RaisePropertyChanged(nameof(Courses));
}
}
private void LoadData()
{
try
{
ObservableCollection<CourseInformation> CourseList = new ObservableCollection<CourseInformation>(_repository.GetAllCourseInformation());
Courses = new ObservableCollection<CourseInformation>();
DateTime date;
foreach (var course in CourseList)
{
string [] cour = course.Date.Split('/');
cour[2] = "20" + cour[2];
date = new DateTime(Convert.ToInt32(cour[2]), Convert.ToInt32(cour[1]), Convert.ToInt32(cour[0]));
if (date == DateTime.Now)//TESTING WITH TEST DATE, datetime.now
{
if (course.FromTime.Length < 4)
{
course.FromTime = "0" + course.FromTime;
}
if (course.UntilTime.Length < 4)
{
course.UntilTime = "0" + course.UntilTime;
}
course.FromTime = course.FromTime.Insert(2, ":");
course.UntilTime = course.UntilTime.Insert(2, ":");
Courses.Add(course);
}
}
}
catch (ServerUnavailableException e)
{
ErrorMessage = "Server is niet beschikbaar, ophalen van kalender is niet mogelijk.";
}
}
private void RaisePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Bootstrap binding in app.xaml.cs:
public partial class App : Application
{
public App()
{
InitializeComponent();
AppContainer.Container = new Bootstrap().CreateContainer();
MainPage = new LoginView();
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
I wanted to comment (not enough reputation) on #LeRoy, use a framework. I would recommend FreshMVVM and you can pass objects into the ViewModel and even pass in Services. It makes it all nice and clean, and it just works.
Should not your CalendarViewModel viewModel contain BindableBase ?
public class CalendarViewModel : BindableBase, ViewModelBase, ICalendarViewModel
what framework are you using? prism, freshmvvm.
Your View and Viewmodel is normally automatically handled by the framework, all you need to do is register your page.
Container.RegisterTypeForNavigation<Views.CalendarPage>();

Xamarin Forms - Reference XAML from Android specific .cs file

I have a page called MapPage.xaml and a code behind called MapPage.xaml.cs. In my android project, I have another file called CustomMapRenderer.cs. In the CustomMapRenderer.cs file, I need to retrieve the item selected variable in a XAML picker found in my MapPage.xaml file, which changes when a user picks an option in my XAML picker.
How to I reference the picker from my CustomMapRenderer.cs?
In the CustomMapRenderer.cs file, I need to retrieve the item selected variable in a XAML picker found in my MapPage.xaml file, which changes when a user picks an option in my XAML picker.
If you followed the official doc Customizing a Map to create your CustomMapRenderer, then in PCL, there should be a class which inherits from Map, for example:
public class CustomMap : Map
{
}
Then, if your picker is another control in your MainPage, you can create a bindable property for your CustomMap, and override OnElementPropertyChanged in your renderer to get this property when it changed.
For example, in PCL:
public class MapWithMyZoomControl : Map
{
public ZoomState MyZoom
{
get { return (ZoomState)GetValue(MyZoomProperty); }
set { SetValue(MyZoomProperty, value); }
}
public static readonly BindableProperty MyZoomProperty =
BindableProperty.Create(
propertyName: "MyZoom",
returnType: typeof(ZoomState),
declaringType: typeof(MapWithMyZoomControl),
defaultValue: ZoomState.normal,
propertyChanged: OnZoomPropertyChanged);
public static void OnZoomPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
}
public enum ZoomState
{
normal,
zoomin,
zoomout
}
}
And in its renderer:
public class MapWithMyZoomControlRenderer : MapRenderer, IOnMapReadyCallback
{
private GoogleMap map;
public void OnMapReady(GoogleMap googleMap)
{
map = googleMap;
map.UiSettings.ZoomControlsEnabled = false;
}
protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// Unsubscribe
}
if (e.NewElement != null)
{
var formsMap = (MapWithMyZoomControl)e.NewElement;
((MapView)Control).GetMapAsync(this);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var element = Element as MapWithMyZoomControl;
if (e.PropertyName == "MyZoom" && map != null)
{
if (element.MyZoom == MapWithMyZoomControl.ZoomState.zoomin)
{
map.AnimateCamera(CameraUpdateFactory.ZoomIn());
}
else if (element.MyZoom == MapWithMyZoomControl.ZoomState.zoomout)
{
map.AnimateCamera(CameraUpdateFactory.ZoomOut());
}
element.MyZoom = MapWithMyZoomControl.ZoomState.normal;
}
}
}
Out of this map control, I use buttons to control to zoom the map:
map.MyZoom = MapWithMyZoomControl.ZoomState.zoomin;
It'a a demo, but you can modify it to make property connected to your picker.

Retrying Event For SqlAzureExecutionStrategy

When working with SQL Azure, if I create my own RetryPolicy, e.g.:
var retryStrategy = new FixedInterval(3, TimeSpan.FromSeconds(10));
var retryPolicySQL = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(retryStrategy);
retryPolicySQL.Retrying += ....;
I am able to get notified when a retry is happening which is useful to log.
However, if I use what seems to be the new recommended strategy with EF6 and Azure - i.e. a custom DbConfiguration class something like this:
public class MyConfiguration : DbConfiguration
{
public MyConfiguration()
{
this.SetExecutionStrategy("System.Data.SqlClient", () =>
{
var strat = new SqlAzureExecutionStrategy();
// strat. No events
return strat;
});
}
}
I can't seem to find a way to hook into the retrying process. Is there a way to do this?
Implement the protected method called ShouldRetryOn by subclassing from SqlAzureExecutionStrategy. In that method you could put your logic to log or hook it into a handler as I show below.
public delegate void ChangedEventHandler(object sender, EventArgs e);
public class MyStrategy : SqlAzureExecutionStrategy
{
public event ChangedEventHandler Changed;
protected override bool ShouldRetryOn(Exception exception)
{
OnChanged(EventArgs.Empty);
return base.ShouldRetryOn(exception);
}
protected virtual void OnChanged(EventArgs e)
{
if (Changed != null)
Changed(this, e);
}
}
If you would perfer to just log the exception or the retry, you can do as follows:
public class LoggedSqlAzureExecutionStrategy : SqlAzureExecutionStrategy
{
protected override bool ShouldRetryOn(Exception exception)
{
var shouldRetry = base.ShouldRetryOn(exception);
if (shouldRetry)
{
// log retry
}
return shouldRetry;
}
}