I am trying to make a "TreeView-like" display in my Windows Phone (7.1) application.
In order to do this, I am using the "ExpanderView" in the Silverlight Toolkit.
So basically, my program adds ExpanderViews inside ExpanderViews in order to create the tree.
Everything is fin until an element exceeds the screen horizontally, where it gives me the exception "The parameter is incorrect." on the "Debugger.Break()" line in the following code:
// Code to execute on Unhandled Exceptions
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (System.Diagnostics.Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}
}
Under App.xaml.cs.
I am assuming the element doesn't initialize/load corrently, as I had this exception before with the same element, where I was adding items without the parent element being fully loaded.
This is my XAML:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid x:Name="ContentPanel" Margin="12,0,12,0"/>
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/Plus.png" Text="Add" Click="ApplicationBarIconButtonClick"/>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
And this is the code behind:
public MainPage()
{
InitializeComponent();
_lastView = new ExpanderView { Header = "Header", IsExpanded = true };
ContentPanel.Children.Add(_lastView);
}
private ExpanderView _lastView;
private void ApplicationBarIconButtonClick(object sender, System.EventArgs e)
{
var newItem = new ExpanderView {Header = "Header", IsExpanded = true};
_lastView.Items.Add(newItem);
_lastView = newItem;
}
The very next time I click the application bar button (when the next element exceeds the screen horizontally), it gives me the exception:
Check last Visual Studio updates. I had same problem before NuGet package update. Restart of Vissual Studio + update helped me
Related
This is my mainpage.xaml.cs :
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
wv.Source = new Uri("https://www.youtube.com");
//wv.Refresh();
}
}
this works - as soon as i run the app YouTube is loaded. But when I uncomment the wv.Refresh it stops working - i see only white background. Also happens when I use wv.Navigate instead of wv.Source.
First of all, you have good questions about WebView :-D .
I have debugged it and it seems that even though the Source is set to the URI, internally the WebView still is pointing to about:blank page and refresh comes too early so the navigation to your URI is cancelled and instead the blank page is refreshed.
I have come up with the following code:
public MainPage()
{
this.InitializeComponent();
webview.NavigationStarting += Webview_NavigationStarting;
}
private void Webview_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args)
{
Debug.WriteLine("Navigating " + args.Uri);
}
private void SetNextSource()
{
var uri = new Uri("https://www.google.com");
Debug.WriteLine("Setting " + uri);
webview.Source = uri;
webview.Refresh();
Debug.WriteLine("Set " + webview.Source);
}
And here is the output:
As you can see in the output, the refresh completely ignored the Source property and most likely used some kind of internal URI.
So to fix your problem, you could just hook up the NavigationCompleted event and do the Refresh() in there instead - as by that time, the WebView will actually finish loading the page and will even internally be pointing to the newly set URI.
MainView include InformationCOmponent:
#Push
#Route
public class MainView extends VerticalLayout {
InformationComponent infoComponent;
public MainView(#Autowired StudentRepository studentRepo, #Autowired Job jobImportCsv, #Autowired JobLauncher jobLauncher, #Value("${file.local-tmp-file}") String inputFile) {
[...] // some stuffs
infoComponent = new InformationComponent(studentRepo);
add(infoComponent);
}
//update when job process is over
private void uploadFileSuccceed() {
infoComponent.update(myUploadComponent.getFile());
}
InformationComponent:
public class InformationComponent extends HorizontalLayout {
StudentRepository studentRepo;
Label nbLineInFile = new Label();
VerticalLayout componentLeft = new VerticalLayout();;
VerticalLayout componentRight = new VerticalLayout();;
public InformationComponent(StudentRepository studentRepo) {
[...] // some init and style stuff
addLine("Nombre de lignes dans le fichier", nbLineInFile);
}
private void addLine(String label, Label value) {
componentLeft.add(new Label(label));
componentRight.add(value);
}
public void update(File file) {
try {
long nbLines = Files.lines(file.toPath(), Charset.defaultCharset()).count();
System.out.println("UPDATED! " +nbLines); // value is display in console ok!
UI.getCurrent().access(() -> nbLineInFile.setText(nbLines)); // UI is not updated!!
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
When I call InformationComponent from MainView the Label is not update in the browser.
UI.getCurrent().access(() -> nbLineInFile.setText(nbLines))
also try wwith #Push(PushMode.MANUAL) and ui.push(); but doesn't work either...
Complete source code is here: https://github.com/Tyvain/ProcessUploadedFile-Vaadin_SpringBatch/tree/push-not-working
I suspect the problem here is that uploadFileSuccceed() is run from a background thread, in which case UI.getCurrent() will return null. This would cause a NullPointerException that either kills the background thread or alternatively the exception is caught and silently ignored by the caller. Another alternative is that uploadFileSuccceed() happens through a different browser window and thus also a different UI instance, which means that the changes would be pushed in the context of the wrong UI.
For exactly these reasons, UI.getCurrent().access(...) is generally an anti pattern, even though it's unfortunately quite widely used in old examples.
You can check whether this is the cause of your problem by logging the value of UI.getCurrent() in the beginning of the update method, and comparing that to the value of UI.getCurrent() e.g. in the constructor of InformationComponent.
To properly fix the problem, you should pass the correct UI instance through the entire chain of events originating from whatever triggers the background processing to start. You should also note that it might be tempting to use the getUI() method that is available in any Component subclass, but that method is not thread safe and should thus be avoided in background threads.
As a final notice, I would recommend using the Span or Text component instead of Label in cases like this. In Vaadin 10, the Label component has been changed to use the <label> HTML element, which means that it's mainly intended to be used as the label of an input component.
Based on information provided by Leif you should do something like the following example.
At runtime, when this HorizontalLayout subclass object is attached to a parent UI object, its onAttach method is called. At that point we can remember the UI by storing its reference is a member variable named ui. Actually, an Optional<UI> is returned rather than a UI object, so we need to test for null, though it should never be null at point of onAttach.
public class InformationComponent extends HorizontalLayout {
UI ui;
StudentRepository studentRepo;
Label nbLineInFile = new Label();
VerticalLayout componentLeft = new VerticalLayout();;
VerticalLayout componentRight = new VerticalLayout();;
public InformationComponent(StudentRepository studentRepo) {
[...] // some init and style stuff
addLine("Nombre de lignes dans le fichier", nbLineInFile);
}
private void addLine(String label, Label value) {
componentLeft.add(new Label(label));
componentRight.add(value);
}
public void update(File file) {
try {
long nbLines = Files.lines(file.toPath(), Charset.defaultCharset()).count();
System.out.println("UPDATED! " +nbLines); // value is display in console ok!
this.ui.access(() -> nbLineInFile.setText(nbLines)); // UI is not updated!!
} catch (IOException e) {
throw new RuntimeException(e);
} catch (UIDetachedException e) {
// Do here what is needed to do if UI is no longer attached, user has closed the browser
}
#Override // Called when this component (this `HorizontalLayout`) is attached to a `UI` object.
public void onAttach() {
ui = this.getUI().orElseThrow( () -> new IllegalStateException("No UI found, which should be impossible at point of `onAttach` being called.") );
}
For my ios application I need to handle those cases where the server returns an error, there are a couple of errors I am interested in handle, such as Not Found and Timed Out.
I'm developing with Xamarin and Windows Azure Mobile Services. So far, I know how to catch these exceptions, however, in case of an exception I would like to show a view that contains a refresh button, which the user can press in order to refresh (go to the server and see if there is new data, remove the refresh view, and display the new info).
this is how I'm capturing the exceptions thrown by the server:
public async RefreshAsync(){
try
{
var results = await DailyWorkoutTable.ToListAsync();
wod = results.FirstOrDefault();
SetupUI();
}
catch(Exception e)
{
var ex = e.GetBaseException() as MobileServiceInvalidOperationException;
if(ex.Response.StatusCode == 404)
{
//this is where I need to set up the refresh view and
//and add a UIButton to it
Console.WriteLine("Daily workout not found");
}
}
}
I don't know what's the right way to accomplish this. If I create a UIView and add a UIButton to it, with an event which calls RefreshAsync again, it will not work and is not the most elegant way to do it.
Is there another approach on this?? please help.
Here is an example you can use as a starting point:
/// <summary>
/// A class for performing Tasks and prompting the user to retry on failure
/// </summary>
public class RetryDialog
{
/// <summary>
/// Performs a task, then prompts the user to retry if it fails
/// </summary>
public void Perform(Func<Task> func)
{
func().ContinueWith(t =>
{
if (t.IsFaulted)
{
//TODO: you might want to log the error
ShowPopup().ContinueWith(task =>
{
if (task.IsCompleted)
Perform(func);
}, TaskScheduler.FromCurrentSynchronizationContext());
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
/// <summary>
/// Wraps a retry/cancel popup in a Task
/// </summary>
private Task ShowPopup()
{
var taskCompletionSource = new TaskCompletionSource<bool>();
var alertView = new UIAlertView("", "Something went wrong, retry?", null, "Ok", "Cancel");
alertView.Dismissed += (sender, e) => {
if (e.ButtonIndex == 0)
taskCompletionSource.SetResult(true);
else
taskCompletionSource.SetCanceled();
};
alertView.Show();
return taskCompletionSource.Task;
}
}
To use it:
var retryDialog = new RetryDialog();
retryDialog.Perform(() => DoSomethingThatReturnsTask());
This example is prior to async/await support, but you can refactor it if desired.
You might also consider making Perform() return a Task and become async -- depending on your use case.
I am using timepicker in my application but whenever I give it a default value then NullReferenceException appears in valuechange function.My code is
private void timePicker1_ValueChanged(object sender, DateTimeValueChangedEventArgs e)
{
var time = (DateTime)timePicker1.Value;
// time.ToShortTimeString()
MessageBox.Show(time.ToString("H:mm"));
writeTimeFile(time);
ResetAlarm();
setTheAlarm();
}
Actually whenever I start my application,the timepicker shows current time but I want it to show some specific value say 00:00 or 12:00.
Make sure you are setting the value of your time picker object correctly. This worked for me. Also verify something else isn't throwing the NullReferenceException.
public TimePage()
{
InitializeComponent();
// setting default value for TimePicker here
EventTimePicker.Value = DateTime.Parse("12:00 AM");
}
private void TimePicker_ValueChanged(object sender, DateTimeValueChangedEventArgs e)
{
var time = (DateTime) EventTimePicker.Value;
MessageBox.Show(time.ToShortTimeString());
}
I am writing an Excel 2007 Addin. using VS2008 and .net 3.5, C#.
I catched Microsoft.Office.Interop.Excel.Application's WindowActivate and WindowDeActivate events.
It was surprised to know that WindowActivate and Deactivate only triggers when i switch between two Excel Windows. if i switch to notepad, i expect Deactivate to be triggered, but its not happening. same way from notepad if i switch to excel window, i expect Activate to be triggered but its not happening. It looks like the behaviour indicates windows are MDI-Child windows.
Now what i want to do is get HWnd of Excel's Mainwindow and hook Window Activate and Deactivates using dllimport features.
Can anyone guide to me on this.
Regards
I solved similar problem when writing Excel addin. No dll import is needed. I solved this issue using System.Windows.Forms.NativeWindow class.
At first, I made my own class inherited from NativeWindow class and declared two events Activated and Deactivate in it and finaly overrided WndProc() method to rise these events when message WM_ACTIVATE is passed to the WndProc method. According to "Message" parameter WParm is Excel window activated or deactivated.
public class ExcelWindow: NativeWindow
{
public const int WM_ACTIVATED = 0x0006;
public ExcelWindow():base(){}
//events
public event EventHandler Activated;
public event EventHandler Deactivate;
//catching windows messages
protected override void WndProc(ref Message m)
{
if (m.Msg== WM_ACTIVATED)
{
if (m.WParam.ToInt32() == 1)
{
//raise activated event
if (Activated!=null)
{
Activated(this, new EventArgs());
}
}
else if (m.WParam.ToInt32() == 0)
{
//raise deactivated event
if (Deactivate!=null)
{
Deactivate(this, new EventArgs());
}
}
}
base.WndProc(ref m);
}
}
Then I made in my addin class field "ExcelWindow myExcelWindow" and added following code to OnConnection method of my addin:
ExcelWindow myExcelWindow;
void Extensibility.IDTExtensibility2.OnConnection(object application, Extensibility.ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
{
excel = application as Excel.Application;
myExcelWindow = new ExcelWindow();
myExcelWindow.AssignHandle(new IntPtr(excel.Hwnd));
myExcelWindow.Activated += new EventHandler(myExcelWindow_Activated);
myExcelWindow.Deactivate += new EventHandler(myExcelWindow_Deactivate);
//addin code here
}
void myExcelWindow_Activated(object sender, EventArgs e)
{
//do some stuff here
}
void myExcelWindow_Deactivate(object sender, EventArgs e)
{
//do some stuff here
}
I hope this will help you.
Finally I found one solution..that works only Activate/Deactivate.
This is not the perfect way to do it. But I did not find any good alternative.
This method uses polling. I have to call following function in each 10 ms interval to check focus in/out.
public static bool ApplicationIsActivated()
{
var activatedHandle = GetForegroundWindow();
if (activatedHandle == IntPtr.Zero)
{
return false; // No window is currently activated
}
var procId = Process.GetCurrentProcess().Id;
int activeProcId;
GetWindowThreadProcessId(activatedHandle, out activeProcId);
return activeProcId == procId;
}