GTK# - PropertyNotifyEvent doesn't seem to work - events

I try to make my app to react on property change of a widget, but the signal PropertyNotifyEvent is never invoke.
For test purpose i make a very simple application containing a label and a button. Pressing the button change text property of label but the PropertyNotifyEvent isn't responding.
using System;
using Gtk;
public partial class MainWindow : Gtk.Window
{
public MainWindow() : base(Gtk.WindowType.Toplevel)
{
Build();
label1.AddEvents((int)(Gdk.EventMask.PropertyChangeMask));
}
protected void OnDeleteEvent(object sender, DeleteEventArgs a)
{
Application.Quit();
a.RetVal = true;
}
protected void OnButton1Clicked(object sender, EventArgs e)
{
label1.Text = "new text";
}
protected void OnLabel1PropertyNotifyEvent(object o, PropertyNotifyEventArgs args)
{
Console.WriteLine("label property change");
}
}
I have no idea what I do wrong, do I missing something?

Found a solution:
label1.AddNotification("label", (o, args) => {Console.WriteLine("label property change");});

Related

Close ModalView on back button.(Xamarin)

I am showing a ModalView(Navigation page) on button click.
Its working well. I want to close Modalview on Back button.
If you have any idea guide me.
My code as follows.
Button click event
protected void btnEdit_Click(object sender, EventArgs e)
{
var navigation = new NavigationPage(new Settings());
UIViewController navc = navigation.CreateViewController();
navc.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
this.PresentViewController(navc, true, null);
}
Setting Form code
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Settings : ContentPage
{
public Settings()
{
var backItem = new ToolbarItem
{
Text = "Back"
};
this.ToolbarItems.Add(backItem);
backItem .SetBinding(MenuItem.CommandProperty, "BackClicked");
backItem .Clicked += (object sender, System.EventArgs e) =>
{
**// This code Not working**
Navigation.PopModalAsync(false);
};
InitializeComponent();
}
}
You appear to be mixing native iOS code with Xamarin.Forms code, as #Jason mentions in the comment. To open a modal view from XamForms, you can call Navigation.PushModal():
protected async void btnEdit_Click(object sender, EventArgs e)
{
var navigation = new NavigationPage(new Settings());
await Navigation.PushModalAsync(navigation);
}
Update based on comment
public class MyTabbarPage : TabbarPage
{
...
public void ButtonClicked()
{
var navigation = new NavigationPage(new Settings());
await Navigation.PushModalAsync(navigation);
}
}
// Inside renderer
protected async void btnEdit_Click(object sender, EventArgs e)
{
(Element as MyTabbarPage).ButtonClicked();
}
I did as below code to call XamForms class function an its worked.
protected void btnEdit_Click(object sender, EventArgs e)
{
Maintabpage obj =(Maintabpage)Xamarin.Forms.Application.Current.MainPage;
obj.ButtonClicked();
}

OnElementPropertyChanged is not triggered in iOS custom renderer

OnElementPropertyChanged is not triggered in iOS custom renderer.
I have created a class library. In my Customer Renderer class i have override a OnElementPropertyChanged and this should be called whenever the Property of my View gets changed.
XamarinForms:
public class CustomControl : View
{
public int PageNumber
{
get { return (int)GetValue(PageNumberProperty); }
set { SetValue(PageNumberProperty, value); }
}
public static readonly BindableProperty PageNumberProperty =
BindableProperty.Create<CustomControl, int>(p => p.PageNumber, 0, BindingMode.Default, null, null);
}
CustomRenderer Class iOS:
[assembly: ExportRenderer(typeof(CustomControl), typeof(CustomRenderer))]
namespace XForms.iOS
{
internal class CustomRenderer : ViewRenderer<CustomControl, UIScrollView>
{
protected override void OnElementChanged(ElementChangedEventArgs<CustomControl> e)
{
base.OnElementChanged(e);
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
}
}
}
Can anyone tell what i am doing wrong?
Please double check that it is really using the custom renderer by putting a breakpoint into it.
Next make sure that you change proper (PageNumber) after creation of the UI element. During the creation process, property change notifications will not be sent. A similar case is described in the Xamarin forums.

EventToCommand using Mvvmlight and xamarin forms

When developing for all three mobile platforms using MvvmLight with Xamarin forms, what is the recommended way of binding an event in the view to a command in the viewmodel for events that do not support the command pattern? Is it possible to use EventToCommand?
Thanks!
Not sure about MVVMLight but what you could do is define the Events in an Interface (IPageLifeCycleEvents) which are implemented in the relevant ViewModel. Within the View you would then set the BindingContext as an instance of type IPageLifeCycleEvents and pass the events from the View to the ViewModel through the interface. E.G.
public interface IPageLifeCycleEvents
{
void OnAppearing ();
void OnDisappearing();
void OnLayoutChanged();
}
public class SampleView : ContentPage
{
public BaseView () {
var lifecycleHandler = (IPageLifeCycleEvents) this.BindingContext;
base.Appearing += (object sender, EventArgs e) => {
lifecycleHandler.OnAppearing();
};
base.Disappearing += (object sender, EventArgs e) => {
lifecycleHandler.OnDisappearing ();
};
base.LayoutChanged += (object sender, EventArgs e) => {
lifecycleHandler.OnLayoutChanged();
};
}
}
public class SampleViewModel : IPageLifeCycleEvents
{
#region IPageLifeCycleEvents Methods
public void OnAppearing ()
{
//Do something here
}
public void OnDisappearing ()
{
//Do something here
}
public void OnLayoutChanged ()
{
//Do something here
}
#endregion
}
in my actual implementations I use a slightly different setup because of the utilisation of IOC and Base models.
Good luck

How to create command menu item with checkbox?

I'm writing a VSPackage and I need to have menu item with checkbox, just like on this sample image below:
I went through this msdn reference regarding .vsct files, bud didn't fine any information explaining how to do it. What I have now is standard menu item with icon and text (code sample from MyPackage.vsct file):
<Buttons>
<Button guid="guidMyPackageCmdSet" id="cmdidMyPackage" type="Button">
<Icon guid="guidImages" id="myPackageBitmap" />
<CommandFlag>TextChanges</CommandFlag>
<CommandFlag>DontCache</CommandFlag>
<CommandFlag>FixMenuController</CommandFlag>
<Strings>
<ButtonText>MyPackage</ButtonText>
</Strings>
</Button>
</Buttons>
I need this additional checkbox. How to do it?
The properties like Checked, Visible, Enabled or Supported can´t be defined via the VSCT file. You need a command handler that controls the command´s state. I´ve created a base class that wraps the creation of the OleMenuCommand instance and handles the command´s BeforeQueryStatus event. This is a slimmed version of my implementation, but it will give you an idea how to solve it...
internal abstract class CommandHandler : IDisposable
{
private readonly OleMenuCommand command;
protected CommandHandler(Guid group, int id)
{
var commandid = CommandID(group, id);
this.command = new OleMenuCommand(this.Invoke, commandId);
this.command.BeforeQueryStatus += this.OnBeforeQueryStatus;
}
protected virtual void OnExecute() { }
protected virtual void OnQueryStatus(QueryStatusEventArgs e) { }
private void Invoke(object sender, EventArgs e)
{
this.OnExecute();
}
private void OnBeforeQueryStatus(object sender, EventArgs e)
{
OleMenuCommand command;
if ((command = sender as OleMenuCommand) != null)
{
var e = new QueryCommandEventArgs
{
Checked = command.Checked,
}
this.OnQueryStatus(e);
command.Checked = e.Checked;
}
}
public void Dispose()
{
this.command.BeforeQueryStatus -= this.OnBeforeQueryStatus;
}
}
public class QueryCommandEventArgs : EventArgs
{
public bool Checked { get; set; }
}
The CommandHandler class allows to control the state of any menu command. Just derive new handler implementations from it and override the OnExecute and OnQueryStatus methods, like...
internal sealed class MyCommand : CommandHandler
{
private bool checked;
public MyCommand() : base(GuidCmdSet, MyCommandId) { }
protected override void OnExecute()
{
this.checked = !this.checked; // toggle checked state
}
protected override void OnQueryStatus(QueryStatusEventArgs e)
{
e.Checked = this.checked;
}
}

Porting console based ui to a GUI one?

As most of you experienced, developing a console app is as easy as:
void mainloop(){
while (1){
giveInstructions();
getInput();
if (!process()) break;
printOutput();
}
}
int main(){
mainloop();
return 0;
}
However, in GUI it becomes an issue.
We can still giveInstructions(), process(), and printOutput(), but getInput() wouldn't work because it relies on an event, usually button click or key down.
How can I port a console app to a gui app with minimum code changes? (preferably do not change the main method, and as little change to the mainloop function as possible)
Note: I'm not too comfortable with threading yet.
Since there is no specific language given, I will show an example in C# where you would be able to use the same code as the console app with a simple GUI.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//using form-editor, double-click buttons or use the following
btnInput.Click += new EventHandler(btnInput_Click);
btnContinue.Click += new EventHandler(btnContinue_Click);
giveInstructions();
}
private void giveInstructions()
{
txtInfo.Text = "";
txtInput.Text = "";
//display instructions to multi-line textbox
}
private void btnInput_Click(object sender, EventArgs e)
{
//or you can just add another button for exit.
if (txtInput.Text == "expected value for exit")
{
Application.Exit();
}
else
{
getInput();
}
}
private void getInput()
{
string strInput = txtInput.Text;
//do stuff
printOutput();
}
private void printOutput()
{
//display output to multi-line textbox
}
private void btnContinue_Click(object sender, EventArgs e)
{
giveInstructions();
}
}

Resources