I've noticed a strange exception in my Windows Phone 7.1 application that really made me crazy.
These are the facts...
I start defining a simple Pivot item with two simple PivotItem inside:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<controls:Pivot>
<controls:PivotItem x:Name="PivotItem1"
Header="Test1" />
<controls:PivotItem x:Name="PivotItem2"
Header="{Binding Path=Text2, Mode=OneWay}" />
</controls:Pivot>
<Button Content="Test" Click="Button_Click" />
</Grid>
And this is my code-behind...
EDIT: As Gambit suggested me, I will show you more code.
In the real situation, I DO HAVE A MVVM, but in this case I simplified the situation to let you reproduce the problem in an easy way...
For this test the next is my View:
public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged
{
private string _text2 = "<Missing>";
public string Text2
{
get
{
return _text2;
}
private set
{
_text2 = value;
NotifyPropertyChanged("Text2");
}
}
public MainPage()
{
InitializeComponent();
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Text2 = "Second page";
}
}
So, it's not just the parameter initialization of a NULL value: you will see the exception.
Obviously, you are asking me for the controls namespace declaration. This is:
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
This refers to the assembly Microsoft.Phone.Controls.dll, version 2.0.50727.
My problem is related to the binding (as I discovered investigating the problem):
Header="{Binding Path=Text2, Mode=OneWay}"
If you do not use bindings linked to the Header property of the PivotItem, everything works well, otherwise...the app will throw an exception, completely silent, and it won't show up in any case (you can see the exception only in the Output Window):
A first chance exception of type 'System.Exception' occurred in System.Windows.dll
If you assign the Header property manually, no exceptions will be thrown.
I want to completely remove this exceptions, because I have a lot of bindings to the Header property, I don't want to break my MVVM...and it's also very annoying!
I really hate to see unmanaged exceptions...
Does anyone know about this problem?
Any solution/workaround?
Any help will be very appreciated...thank you!
Based on the code provided, I would suspect that the issue is the DataContext is not being set. In your example, the DataContext is set in the PhoneApplicationPage_Loaded event. However, it doesn't appear that you are registering for this event anywhere. In the constructor of MainPage, add a line like:
this.Loaded += new RoutedEventHandler(PhoneApplicationPage_Loaded);
Related
I am trying to attach an event handler in ListView with Microsoft.Xaml.Interactivity in my UWP application. When I select a row in ListView, the application executes a procedure according to the selected item.
So, I've installed the "Microsoft.Xaml.Behaviors.Uwp.Managed" package and changed a XAML file like this:
<ListView VerticalAlignment="Stretch"
x:Name="listBoxobj"
HorizontalAlignment="Stretch"
Margin="10,0,0,10"
Background="White"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Tools}"
SelectedItem= "{Binding SelectedItem, Mode=Twoway}"
SelectionMode="Single">
<Interactivity:Interaction.Behaviors>
<Interactions:EventTriggerBehavior EventName="ItemClick" SourceObject="listBoxObj">
<Interactions:InvokeCommandAction Command="{Binding Tool_Clicked}" CommandParameter="{Binding SelectedItem}" />
</Interactions:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
And the following has been implemented in its ViewModel:
private System.Windows.Input.ICommand tool_Clicked;
public ICommand Tool_Clicked
{
get {
return tool_Clicked;
}
set {
if (!Object.ReferenceEquals(tool_Clicked, value))
{
tool_Clicked = value as RelayCommand;
OnPropertyChanged("Tool_Clicked");
}
}
}
public DisplayViewModel()
{
...
Tool_Clicked = new RelayCommand(SelectionChanged);
...
}
public void SelectionChanged(object arg) {
... executes some procedures according to the selected item...
}
But when I tested these codes, the following exception has emitted:
System.TypeLoadException: 'Could not find Windows Runtime type 'System.Windows.Input.ICommand'.'
In Debug mode, on the other hand, no such exception has been thrown.
So, I have two questions:
I wonder what is the difference betweeen the Debug mode and the Release mode.
Are there any way to avoid throwing the System.TypeLoadException?
Update 1:
I have configured the compile options at Release mode.
I've checked "Compile with .NET native tool chain"
I've checked "unsafe code".
But when I tried to build my project, it has ended with the following error message:
error : MCG0018:TypeExpected Type File or assembly 'System.Runtime.InteropServices.WindowsRuntime.PropertyType' not found.
When I tried unchecking "Compile with .NET native tool chain", I could run this code. I think some of the nuget packages I use don't support .NET native code...
Update 2:
I've made the RelayCommand class like the following:
public class RelayCommand : ICommand
{
private readonly Action<Object> _execute;
private readonly Func<object, bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action<object> execute) :
this(execute, null)
{ }
public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
{
_execute = execute ?? throw new ArgumentNullException("execute");
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
I noticed that your question has been solved on Microsoft Q&A-System.TypeLoadException occurs in the Release Mode by Nico.
To make Nico's answer short, you could use the Tapped event instead of using the click event. Then you could use the current datacontext as parameter
Code like this:
<DataTemplate>
<TextBlock Text="{Binding}">
<Interactivity:Interaction.Behaviors>
<Interactions:EventTriggerBehavior EventName="Tapped">
<Interactions:InvokeCommandAction Command="{Binding ElementName=listBoxObj, Path=DataContext.Tool_Clicked}" CommandParameter="{Binding}" />
</Interactions:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</TextBlock>
</DataTemplate>
I have this C# code
public static class AS
{
public static bool ss; // Show Subcategory
}
public SettingsPage()
{
InitializeComponent();
}
void SsSwitch(object sender, ToggledEventArgs e)
{
App.DB.UpdateBoolSetting(Settings.Ss, e.Value);
//
// code here will update the value of AS.ss
// after the database has been updated
//
}
this XAML
<SwitchCell x:Name="SWCData" Text="Select Your Network"
On="{Binding AS.ss}" OnChanged="SsSwitch" />
I am getting a message saying that no property or bindable property for the view.
Can anyone give me help on this?
If you are binding static class then refer the below code to bind
<SwitchCell Text="Select Your Network"
On="{Binding Source={x:Static local:AS.ss}}" OnChanged="SsSwitch" />
I'm using listview like following at my Xamarin.Form, and I noticed a issue this code will register the listView's selected event again everytime when I use back button comeback to this page.
protected override void OnAppearing()
{
listView.ItemSelected += new EventHandler<SelectedItemChangedEventArgs>(OnItemSelected);
// or this same issue. listView.ItemSelected += OnItemSelected;
}
private void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
Navigation.PushAsync(GotoOtherPage);
}
<ListView ItemsSource="{Binding MyList}" x:Name ="listView" CachingStrategy="RecycleElement" AutomationId="listView">
My fix is following add Selected Event at xaml. However sometime I have generated the control at C#, is there other way to register event at backend C# code.
<ListView ItemSelected="OnItemSelected" x:Name ="listView" ItemsSource="{Binding MyList}" CachingStrategy="RecycleElement" AutomationId="listView">
Having your event handler
void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
{
Navigation.PushAsync(GotoOtherPage);
}
The way to do a safe subscription to the ItemSelected event of the ListView would be:
Subscribe your events in the OnAppeaning method
protected override void OnAppearing()
{
base.OnAppearing();
listView.ItemSelected += OnItemSelected;
}
Unsubscribe in the OnDisappearing:
protected override void OnDisappearing()
{
base.OnDisappearing();
listView.ItemSelected -= OnItemSelected;
}
Also notice it's not necessary to create an instance of EventHandler to attach the event handler to the event.
I think you should register the event in construct function, not in OnAppearing function.
I am trying to get a function to be called everytime an event occurs. In the KinectRegion class there is an event called HandPointerGrip: http://msdn.microsoft.com/en-us/library/microsoft.kinect.toolkit.controls.kinectregion.handpointergrip.aspx.
I see that it has declared the event and it seems to me that the event has already been set to be invoked(HandPointerEventArgs)? How do I attach a function to this event?
public Menu()
{
KinectRegion.HandPointerGripEvent+=Hand_Gripped; // why doesn't this work? :(
}
private void Hand_Gripped(object sender, HandPointerEvnetArgs e)
{
MessageBox.Show("I work!"); // I wish this would work
}
Been working hard on this problem and here is something I think will work. Afraid to test it. Learning a lot about routed events, delegates, and events.
namespace ...
{
public delegate void HandPointerEventHandler(object sender, HandPointerEventArgs e);
public partial class thePage : Page
{
public event HandPointerEventHandler HandGripped
{
add {this.AddHandler(KinectRegion.HandPointerGripEvent,value);}
remove {this.RemoveHandler(KinectRegion.HandPointerGripEvent,vlaue);}
}
public thePage()
{
InitializeComponent();
this.HandGripped += new HandPointerEventHandler(OnHandGripped);
}
protected virtual void OnHandGripped(object sender, HandPointerEventArgs e)
{
MessageBox.Show("hello"); //hopefully
}
}
}
The first block of code should work fine. My guess is that the HandPointerGripEvent is hooked up ok, it just never fires.
How are you setting up your KinectRegion?
Are you updating the interration library each frame?
Perhaps this helps?
Kinect SDK 1.7: Mapping Joint/Cursor Coordinates to screen Resolution
KinectRegion.AddHandPointerGripHandler(this.Button1, this.Button1_Click);
Here Button1 is:
< k:KinectTileButton x:Name="Button1" Height="150" Width="150" Content="Click"/ >
The namespaces:
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:k="http://schemas.microsoft.com/kinect/2013"
Button1_Click is the method itself, for example:
private void Button1_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("YOU GOT ME !!!");
}
If you want to add a grip handler for another interface object, you just do:
KinectRegion.AddHandPointerGripHandler(< object name >, < method name >);
And s.o.
I have a problem with localization of Silverlight application using resources. I wanted to make my multilingual mechanizm to be cross platform thats why I placed all localizable resources in project of type Portable Class Library.
In this project I created two resource files
Localization.resx and Localization.en.resx and I set and "access modifier" to public in both files. Then I created the proxy class called "LocalizationProxy" which is a proxy class to enable bindings.
public class LocalizationProxy : INotifyPropertyChanged
{
public Localization LocalizationManager { get; private set; }
public LocalizationProxy()
{
LocalizationManager = new Localization();
}
public void ResetResources()
{
OnPropertyChanged(() => LocalizationManager);
}
#region INotifyPropertyChanged region
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged<T>(Expression<Func<T>> selector)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(GetPropertyNameFromExpression(selector)));
}
}
public static string GetPropertyNameFromExpression<T>(Expression<Func<T>> property)
{
var lambda = (LambdaExpression)property;
MemberExpression memberExpression;
if (lambda.Body is UnaryExpression)
{
var unaryExpression = (UnaryExpression)lambda.Body;
memberExpression = (MemberExpression)unaryExpression.Operand;
}
else
{
memberExpression = (MemberExpression)lambda.Body;
}
return memberExpression.Member.Name;
}
#endregion
}
In the next step I modifed Silverlight csproj file and added "en" culture to supported types
<SupportedCultures>en</SupportedCultures>
Furthermore in application resources I created and instance of LocalizationProxy class
<Application.Resources>
<Localization:LocalizationProxy x:Key="LocalizationProxy"></Localization:LocalizationProxy>
</Application.Resources>
I also changed "Neutral Language" in Assembly Information to "Polish" - this should be default application language. In the last step I bouned some values from view to the resources
<TextBlock TextWrapping="Wrap" x:Name="PageTitle" Text="{Binding Source={StaticResource LocalizationProxy},Path=LocalizationManager.Title,Mode=TwoWay}" />
Unfortunatelly despite the fact that Thread.CurrentThread.CurrentCulture is "pl-PL" my application is still in English language.However if I use the same code in Windows Phone application everything works fine - I can even change application language in runtime. Is there any difference in localizing Silverlight application and localizing Windows Phone apps ?
Here is my application
http://www.fileserve.com/file/TkQkAhV/LocalizationSolution.rar
As I mentioned before, Localization in Windows Phone works fine, but in Silverlight application labels are not translated
You should use the fully qualified ISO 3166 and 639 codes combined with a hyphen as Rumplin describes.
see
http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
http://en.wikipedia.org/wiki/ISO_3166-1
make sure you made all the steps bellow properly.
Create your ViewModel Class
Implement the INotifyPropertyChanged interface:
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Create the property that will return the right language:
public object MainResourcesSmart
{
get
{
var myCulture = Thread.CurrentThread.CurrentUICulture.Name.ToUpper();
switch (myCulture)
{
case "EN-US":
return new MyResourceEn();
case "ES-AR":
return new MyResourceEs();
default:
return new MyResource();
}
}
}
Set all resources to public
Use the method bellow to refresh it on screen every time you change the language:
private void MainResourcesSmartRefresh()
{
OnPropertyChanged("MainResourcesSmart");
}
Bind the ViewModel to your View (MainPage) for example:
public MyViewModel ViewModel
{
get { return (MyViewModel)DataContext; }
set { DataContext = value; }
}
public MainPage()
{
ViewModel = new MyViewModel();
}
Bind the Resouce property to your UserControl like:
<TextBlock Height="20" HorizontalAlignment="Left" VerticalAlignment="Bottom" Foreground="#7F4F8AB2" FontSize="10.667" Text="{Binding MainResourcesSmart.NameOfTheCompany}" FontFamily="Trebuchet MS" />