Draggable windows forms bar - windows-forms-designer

I am making a windows forms app just to test out my designing skills, but I find that the outline is ugly, so I made my own Minimise and Close buttons, but I'm not sure how to make a pannel that you can drag around. Can anyone help me?
By the way, the code is C#.

Using events we can take the current location when we leftclick (MouseDown) and on MouseMove, we take the current window location minus where we were before and add the distance we've dragged our mouse.
public partial class Form1 : Form
{
private Point windowLocation;
public Form1()
{
InitializeComponent();
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
this.windowLocation = e.Location;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// Refers to the Form location (or whatever you trigger the event on)
this.Location = new Point(
(this.Location.X - windowLocation.X) + e.X,
(this.Location.Y - windowLocation.Y) + e.Y
);
this.Update();
}
}
}

Related

How to use PKPaymentButton in Xamarin.Forms

I have a page in Xamarin.Forms in which I have to show PKPaymentButton by using the same PKPaymentButton class which is a child of UIButton in PassKit.
I have written a custom ButtonRenderer and trying to convert the button into PKPayment button.
I got so far that in custom renderer we can change the appearance of a button but can we use something like creating a new button instance in my case PKPaymentButton and replace it with Button.
UPDATE-
I have achieved this by-
public class ApplePayButtonRenderer : Xamarin.Forms.Platform.iOS.ButtonRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
var button = new PKPaymentButton(PKPaymentButtonType.Buy, PKPaymentButtonStyle.Black);
SetNativeControl(button);
}
}
}
Now I am trying to get its click into Xamarin.Forms
You could use Messaging Center to send message when you click the payment Button.
in Custom Renderer
var button = new PKPaymentButton(PKPaymentButtonType.Buy, PKPaymentButtonStyle.Black);
button.TouchUpInside += Button_TouchUpInside;
SetNativeControl(button);
private void Button_TouchUpInside(object sender, EventArgs e)
{
MessagingCenter.Send<Object>(this,"PayButtonClick");
}
in Forms
Add the following code to the constructor of the ContentPage which contains the Payment Button
public xxxPage()
{
InitializeComponent();
MessagingCenter.Subscribe<Object>(this, "PayButtonClick",(args)=> {
//do some thing you want
});
}

Xamarin forms check if keyboard is open or not

Is there any way to check if keyboard is open or not in Xamarin Forms? Are there any events getting fired when the keyboard opens or closes? If so, where can I find an example of it?
I don't believe that there's a Xamarin.Forms way of doing it. Anyway, for the different platforms (at least Android and iOS) there is a way to achieve what you want.
Android
Under android there is InputMethodManager class. You can obtain it from your activity
var inputMethodManager = (InputMethodManager)this.GetSystemService(Context.InputMethodService);
Now you can check if the keyboard is shown with
var keyboardIsShown = inputMethodManager.IsAcceptingText;
According to this article on CodeProject you can use a class derived from IOnGlobalLayoutListener to listen to global layout events. When this event has fired, you can use the code above to check, if the layout has been changed due to the keyboard popping up.
iOS
Under iOS you may use UIKeyboard class which allows you to observe the DidShowNotification (see here).
notification = UIKeyboard.Notifications.ObserveDidShow ((sender, args) => {
Debug.WriteLine("Keyboard is shown.");
// whatever
});
similarly you can observe DidHideNotification (and some others - see here).
Xamarin.Forms
To implement the keyboard-notification in your Xamarin.Forms the easiest way will be to implement platform dependencies which are resolved with the DependencyService. To do this, you'll first have to introduce an interface for the platform service.
public interface IKeyboardService
{
event EventHandler KeyboardIsShown;
event EventHandler KeyboardIsHidden;
}
In your platform specific projects you'll have to implement the functionality in a platform specific way. See the following code section for iOS implementation
[assembly: Xamarin.Forms.Dependency(typeof(Your.iOS.Namespace.KeyboardService))]
namespace Your.iOS.Namespace
{
public class KeyboardService : IKeyboardService
{
public event EventHandler KeyboardIsShown;
public event EventHandler KeyboardIsHidden;
public KeyboardService()
{
SubscribeEvents();
}
private void SubscribeEvents()
{
UIKeyboard.Notifications.ObserveDidShow(OnKeyboardDidShow);
UIKeyboard.Notifications.ObserveDidHode(OnKeyboardDidHide);
}
private void OnKeyboardDidShow(object sender, EventArgs e)
{
KeyboardIsShown?.Invoke(this, EventArgs.Empty);
}
private void OnKeyboardDidHide(object sender, EventArgs e)
{
KeyboardIsHidden?.Invoke(this, EventArgs.Empty);
}
}
}
The Xamarin.Forms.Dependency makes the class visible to the DependencyService. See the following code for Android implementation
[assembly: Xamarin.Forms.Dependency(typeof(Your.Android.Namespace.KeyboardService))]
namespace Your.Android.Namespace
{
public class KeyboardService : IKeyboardService
{
public event EventHandler KeyboardIsShown;
public event EventHandler KeyboardIsHidden;
private InputMethodManager inputMethodManager;
private bool wasShown = false;
public KeyboardService()
{
GetInputMethodManager();
SubscribeEvents();
}
public void OnGlobalLayout(object sender, EventArgs args)
{
GetInputMethodManager();
if(!wasShown && IsCurrentlyShown())
{
KeyboardIsShown?.Invoke(this, EventArgs.Empty);
wasShown = true;
}
else if(wasShown && !IsCurrentlyShown())
{
KeyboardIsHidden?.Invoke(this, EventArgs.Empty);
wasShown = false;
}
}
private bool IsCurrentlyShown()
{
return inputMethodManager.IsAcceptingText;
}
private void GetInputMethodManager()
{
if (inputMethodManager == null || inputMethodManager.Handle == IntPtr.Zero)
{
inputMethodManager = (InputMethodManager)this.GetSystemService(Context.InputMethodService);
}
}
private void SubscribeEvents()
{
((Activity)Xamarin.Forms.Forms.Context).Window.DecorView.ViewTreeObserver.GlobalLayout += this.OnGlobalLayout;
}
}
}
In your Xamarin.Forms app you can now obtain an instance of the correct implementation of IKeyboardService with
var keyboardService = Xamarin.Forms.DependencyService.Get<IKeyboardService>();
In Xamarin Forms in ANDROID CODE change
(InputMethodManager)this.GetSystemService(Context.InputMethodService);
with
(InputMethodManager)Xamarin.Forms.Forms.Context.GetSystemService(Context.InputMethodService);
You need to change:
var inputMethodManager = (InputMethodManager)this.GetSystemService(Context.InputMethodService);
To:
InputMethodManager inputMethodManager = (InputMethodManager)((Activity)Android.App.Application.Context).GetSystemService(Context.InputMethodService);

How to keep button enabled after closing the form

I'm trying to make a system and I'm having trouble with buttons being disabled.
I have a function that makes the button on a another form enable the button on the main form but whenever I get back to the main form the button becomes disabled again.
How do I keep this permanent even after closing the program? Can I save it in a database to keep its function enabled even if its default is disabled?
Here's the picture of what it looks like:
Thanks for the help.
Take two buttons - "button1" and "button2" on "MainForm" Form.
Set property Enabled=false for "button1"
MainForm.cs
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
Form2 oFrm2 = new Form2();
oFrm2.evtFrm += new ShowFrm(oFrm2_evtFrm);
oFrm2.Show();
}
void oFrm2_evtFrm()
{
button1.Enabled = true;
}
}
Take one button - "button1" on "Form2" Form.
Form2.cs
public delegate void ShowFrm();
public partial class Form2 : Form
{
public event ShowFrm evtFrm;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (evtFrm != null)
{
evtFrm();
}
}
}
MainForm will display first.
Click on "button2" to display "Form2".
On "Form2", click on "button1" to make enable "button1" of "MainForm"
If you want to make "button1" enable permanent, you have to store value - "button1" is enable or disable.

Rearranging parent-child activation order in Caliburn Micro

During my override of OnActivate() in my view-model, I need to call GetView() in order to focus an element. When I do this after I have previously activated my view, it's fine. But when I call this the first activation, it fails.
I was able to get it to work by swapping a few lines in ConductorBaseWithActiveItem.ChangeActiveItem. The original is as follows:
protected virtual void ChangeActiveItem(T newItem, bool closePrevious) {
ScreenExtensions.TryDeactivate(activeItem, closePrevious);
newItem = EnsureItem(newItem);
if(IsActive)
ScreenExtensions.TryActivate(newItem);
activeItem = newItem;
NotifyOfPropertyChange("ActiveItem");
OnActivationProcessed(activeItem, true);
}
and with my changes:
protected virtual void ChangeActiveItem(T newItem, bool closePrevious) {
ScreenExtensions.TryDeactivate(activeItem, closePrevious);
newItem = EnsureItem(newItem);
activeItem = newItem;
NotifyOfPropertyChange("ActiveItem");
if (IsActive)
ScreenExtensions.TryActivate(newItem);
OnActivationProcessed(activeItem, true);
}
This seems to work. Notifying that "ActiveItem" changed triggers the code to load and cache the view. Then ScreenExtensions.TryActivate calls my OnActivate override.
Question: I haven't noticed any problems doing this, but I'm curious if anyone knows better than I do what repercussions this change could have?
Thanks!
One thing you could try is overriding Caliburn's OnViewAttached method and trying to focus it there. That being said, in MVVM, focus is more of a View concern, so if possible, that logic should be moved from the ViewModel to the View.
One way you may be able to solve this is by creating an attached behavior (you will need a reference to the Microsoft.Expression.Interactions assembly):
public class FocusWhenVisibleBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
this.AssociatedObject.Loaded += this.Loaded;
this.AssociatedObject.IsVisibleChanged += this.VisibleChanged;
}
protected override void OnDetaching()
{
this.AssociatedObject.Loaded -= this.Loaded;
this.AssociatedObject.IsVisibleChanged -= this.VisibleChanged;
}
private void Loaded(object sender, RoutedEventArgs e)
{
this.TryFocus();
}
private void VisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
this.TryFocus();
}
private void TryFocus()
{
if (this.AssociatedObject.IsLoaded && this.AssociatedObject.IsVisible)
{
// Focus the control
this.AssociatedObject.Focus();
}
}
}
And that attaching that behavior to whatever control you want to focus:
<Button>
<i:Interaction.Behaviors>
<b:FocusWhenVisibleBehavior/>
</i:Interaction.Behaviors>
</Button>

AspectJ capture button clicked

I want to know whether how to capture the button clicked with AspectJ and get its parameter (eg. button name). I think for having more generalized capturing with AspectJ, it shoudl be used MouseListener so it can capture other UI elements in general!
Example:
In a GUI example I have defined 2 buttons that take some actions
public JButton btn1 = new JButton("Test1");
public JButton btn2 = new JButton("Test2");
btn1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//take some actions
}
}
btn2.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//take some actions
}
}
How to capture these buttons with AspectJ, and get their parameters (eg. name)?
It is possible. I have provided two examples. The first that prints out for every JButton that has an ActionListener. The other example only prints out if a specific buttons is clicked.
Prints the text for every JButton clicked with an ActionListener:
#Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent)")
public void buttonPointcut(ActionEvent actionEvent) {}
#Before("buttonPointcut(actionEvent)")
public void beforeButtonPointcut(ActionEvent actionEvent) {
if (actionEvent.getSource() instanceof JButton) {
JButton clickedButton = (JButton) actionEvent.getSource();
System.out.println("Button name: " + clickedButton.getText());
}
}
Prints the text for a specific JButton:
public static JButton j1;
#Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent) && if()")
public static boolean button1Pointcut(ActionEvent actionEvent) {
return (actionEvent.getSource() == j1);
}
#Before("button1Pointcut(actionEvent)")
public void beforeButton1Pointcut(ActionEvent actionEvent) {
// logic before the actionPerformed() method is executed for the j1 button..
}
UPDATED:
You can do this in many different ways. For example add your buttons to the aspect directly. But I prefere to use a enum object between (ButtonManager in this case), so the code does not know about the aspect. And since the ButtonManager is an enum object, it is easy for the aspect to retrieve values from it.
I just tested it with a Swing button class from Oracle and it works. In the Swing class:
b1 = new JButton("Disable middle button", leftButtonIcon);
ButtonManager.addJButton(b1);
AspectJ is extremely powerful when it comes to manipulating classes, but it can not weave advises into specific objects since objects is not created at the time of weaving. So you can only work with objects at runtime and that is why I have added the addJButton(..) method above. That enables the aspect to check the advised button against a list of registered buttons.
The ButtonManager class:
public enum ButtonManager {
;
private static Collection<JButton> buttonList = new LinkedList<JButton>();
public static void addJButton(JButton jButton) {
buttonList.add(jButton);
}
public static Collection<JButton> getButtonList() {
return buttonList;
}
}
Modified pointcut and advice to only print the name of the buttons registered in the ButtonManager:
#Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent) && if()")
public static boolean buttonListPointcut(ActionEvent actionEvent) {
Collection<JButton> buttonList = ButtonManager.getButtonList();
JButton registeredButton = null;
for (JButton jButton : buttonList) {
if (actionEvent.getSource() == jButton) {
registeredButton = jButton;
}
}
return registeredButton != null;
}
#Before("buttonListPointcut(actionEvent)")
public void beforeButtonListPointcut(ActionEvent actionEvent) {
JButton clickedButton = (JButton) actionEvent.getSource();
System.out.println("Registered button name: " + clickedButton.getText());
}
UPDATED 2
Okay, I believe I understand what you want. You want to listen to mouse events. That is possible. The downside is that you have to register all your GUI components that you want to listen for clicks with a mouse listener. It is not enough to register the JPanel of the JFrame with a MouseListener. So if you only have registered an ActionListener for your buttons, you also have to add a mouse listener.
I have created a quick solution that works for me. It only shows that it works. I have not tried to make the solution generic with many different GUI objects. But that should be quite easy to refactor in when you have got the basics to work.
In the Swing class:
private class MouseListener extends MouseInputAdapter {
public void mouseClicked(MouseEvent e) {}
}
In the init method of the Swing class:
MouseListener myListener = new MouseListener();
btn1.addMouseListener(myListener);
btn2.addMouseListener(myListener);
In the Aspect class:
#Pointcut("execution(* *.mouseClicked(*)) && args(mouseEvent)")
public void mouseEventPointcut(MouseEvent mouseEvent) {}
#Before("mouseEventPointcut(mouseEvent)")
public void beforeMouseEventPointcut(MouseEvent mouseEvent) {
if (mouseEvent.getSource() instanceof JButton) {
JButton clickedButton = (JButton) mouseEvent.getSource();
System.out.println("aspectJ --> mouseClicked: " + clickedButton.getText());
}
}
This results in the following output in the console:
aspectJ --> mouseClicked: Test1
I hope it helps!

Resources