diff --git a/TelegramBaseTest/Tests/Controls/ButtonGridForm.cs b/TelegramBaseTest/Tests/Controls/ButtonGridForm.cs
new file mode 100644
index 0000000..86cb07c
--- /dev/null
+++ b/TelegramBaseTest/Tests/Controls/ButtonGridForm.cs
@@ -0,0 +1,79 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TelegramBotBase.Controls;
+using TelegramBotBase.Form;
+
+namespace TelegramBaseTest.Tests.Controls
+{
+ public class ButtonGridForm : AutoCleanForm
+ {
+
+ ButtonGrid m_Buttons = null;
+
+ public ButtonGridForm()
+ {
+ this.DeleteMode = TelegramBotBase.Enums.eDeleteMode.OnLeavingForm;
+
+ this.Init += ButtonGridForm_Init;
+ }
+
+ private async Task ButtonGridForm_Init(object sender, TelegramBotBase.Base.InitEventArgs e)
+ {
+ m_Buttons = new ButtonGrid();
+
+ await m_Buttons.SetKeyboardType(TelegramBotBase.Enums.eKeyboardType.InlineKeyBoard);
+
+ ButtonForm bf = new ButtonForm();
+
+ bf.AddButtonRow(new ButtonBase("Back", "back"), new ButtonBase("Switch Keyboard", "switch"));
+
+ bf.AddButtonRow(new ButtonBase("Button1", "b1"), new ButtonBase("Button2", "b2"));
+
+ bf.AddButtonRow(new ButtonBase("Button3", "b3"), new ButtonBase("Button4", "b4"));
+
+ m_Buttons.ButtonsForm = bf;
+
+ m_Buttons.ButtonClicked += Bg_ButtonClicked;
+
+ this.AddControl(m_Buttons);
+
+
+ }
+
+ private async void Bg_ButtonClicked(object sender, TelegramBotBase.Base.ButtonClickedEventArgs e)
+ {
+ if (e.Button == null)
+ return;
+
+ if (e.Button.Value == "back")
+ {
+ var start = new Start();
+ await this.NavigateTo(start);
+ }
+ else if (e.Button.Value == "switch")
+ {
+ switch (m_Buttons.KeyboardType)
+ {
+ case TelegramBotBase.Enums.eKeyboardType.ReplyKeyboard:
+ await m_Buttons.SetKeyboardType(TelegramBotBase.Enums.eKeyboardType.InlineKeyBoard);
+ break;
+ case TelegramBotBase.Enums.eKeyboardType.InlineKeyBoard:
+ await m_Buttons.SetKeyboardType(TelegramBotBase.Enums.eKeyboardType.ReplyKeyboard);
+ break;
+ }
+
+
+ }
+ else
+ {
+
+ await this.Device.Send($"Button clicked with Text: {e.Button.Text} and Value {e.Button.Value}");
+ }
+
+
+ }
+ }
+}
diff --git a/TelegramBaseTest/Tests/Start.cs b/TelegramBaseTest/Tests/Start.cs
index e85550c..158f9bc 100644
--- a/TelegramBaseTest/Tests/Start.cs
+++ b/TelegramBaseTest/Tests/Start.cs
@@ -123,6 +123,15 @@ namespace TelegramBaseTest.Tests
await this.NavigateTo(tb);
+ break;
+ case "buttongrid":
+
+ message.Handled = true;
+
+ var bg = new Controls.ButtonGridForm();
+
+ await this.NavigateTo(bg);
+
break;
}
@@ -150,6 +159,8 @@ namespace TelegramBaseTest.Tests
btn.AddButtonRow(new ButtonBase("#11 ToggleButtons", new CallbackData("a", "togglebuttons").Serialize()));
+ btn.AddButtonRow(new ButtonBase("#12 ButtonGrid", new CallbackData("a", "buttongrid").Serialize()));
+
await this.Device.Send("Choose your test:", btn);
}
diff --git a/TelegramBotBase/Controls/ButtonGrid.cs b/TelegramBotBase/Controls/ButtonGrid.cs
new file mode 100644
index 0000000..dc48c68
--- /dev/null
+++ b/TelegramBotBase/Controls/ButtonGrid.cs
@@ -0,0 +1,212 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Telegram.Bot.Types;
+using Telegram.Bot.Types.ReplyMarkups;
+using TelegramBotBase.Base;
+using TelegramBotBase.Enums;
+using TelegramBotBase.Form;
+
+namespace TelegramBotBase.Controls
+{
+ public class ButtonGrid : Base.ControlBase
+ {
+
+ public String Title { get; set; } = "Toggle";
+
+ private bool RenderNecessary = true;
+
+ private static readonly object __evButtonClicked = new object();
+
+ private readonly EventHandlerList Events = new EventHandlerList();
+
+ public ButtonForm ButtonsForm { get; set; }
+
+ public int? MessageId
+ {
+ get
+ {
+ return m_iMessageId;
+ }
+ set
+ {
+ m_iMessageId = value;
+ }
+ }
+
+ private int? m_iMessageId = null;
+
+ ///
+ /// Defines which type of Button Keyboard should be rendered.
+ ///
+ public eKeyboardType KeyboardType
+ {
+ get; private set;
+ }
+
+ public async Task SetKeyboardType(eKeyboardType type)
+ {
+ if (KeyboardType == type)
+ return;
+
+ this.RenderNecessary = true;
+
+ Cleanup().Wait();
+
+ KeyboardType = type;
+
+ }
+
+ private bool m_bVisible = true;
+
+ public ButtonGrid()
+ {
+ this.ButtonsForm = new ButtonForm();
+
+
+ }
+
+ public ButtonGrid(ButtonForm form)
+ {
+ this.ButtonsForm = form;
+ }
+
+
+ public event EventHandler ButtonClicked
+ {
+ add
+ {
+ this.Events.AddHandler(__evButtonClicked, value);
+ }
+ remove
+ {
+ this.Events.RemoveHandler(__evButtonClicked, value);
+ }
+ }
+
+ public void OnButtonClicked(ButtonClickedEventArgs e)
+ {
+ (this.Events[__evButtonClicked] as EventHandler)?.Invoke(this, e);
+ }
+
+ public async override Task Load(MessageResult result)
+ {
+ if (this.KeyboardType != eKeyboardType.ReplyKeyboard)
+ return;
+
+
+ var button = ButtonsForm.ToList().FirstOrDefault(a => a.Text == result.MessageText);
+
+ if (button == null)
+ return;
+
+ OnButtonClicked(new ButtonClickedEventArgs(button));
+
+ result.Handled = true;
+
+ }
+
+ public async override Task Action(MessageResult result, string value = null)
+ {
+ if (result.Handled)
+ return;
+
+ await result.ConfirmAction();
+
+ //Find clicked button depending on Text or Value (depending on markup type)
+ switch (this.KeyboardType)
+ {
+ case eKeyboardType.InlineKeyBoard:
+
+ var button = ButtonsForm.ToList().FirstOrDefault(a => a.Value == result.RawData);
+
+ if (button == null)
+ return;
+
+ OnButtonClicked(new ButtonClickedEventArgs(button));
+
+ result.Handled = true;
+
+ break;
+ }
+
+ }
+
+ public async override Task Render(MessageResult result)
+ {
+ if (!this.RenderNecessary)
+ return;
+
+ Message m = null;
+ if (this.MessageId != null)
+ {
+ switch (this.KeyboardType)
+ {
+ //Reply Keyboard could only be updated with a new keyboard.
+ case eKeyboardType.ReplyKeyboard:
+ if (this.ButtonsForm.Count == 0)
+ {
+ await this.Device.Send("", new ReplyKeyboardRemove());
+ this.MessageId = null;
+ }
+ else
+ {
+ m = await this.Device.Send(this.Title, (ReplyKeyboardMarkup)this.ButtonsForm, disableNotification: true);
+ }
+
+ break;
+
+ case eKeyboardType.InlineKeyBoard:
+ m = await this.Device.Edit(this.MessageId.Value, this.Title, (InlineKeyboardMarkup)this.ButtonsForm);
+ break;
+ }
+
+
+ }
+ else
+ {
+ switch (this.KeyboardType)
+ {
+ case eKeyboardType.ReplyKeyboard:
+ m = await this.Device.Send(this.Title, (ReplyKeyboardMarkup)this.ButtonsForm, disableNotification: true);
+ break;
+
+ case eKeyboardType.InlineKeyBoard:
+ m = await this.Device.Send(this.Title, (InlineKeyboardMarkup)this.ButtonsForm, disableNotification: true);
+ break;
+ }
+
+ if (m != null)
+ {
+ this.MessageId = m.MessageId;
+ }
+ }
+
+ this.RenderNecessary = false;
+
+ }
+
+
+ public async override Task Cleanup()
+ {
+ if (this.MessageId == null)
+ return;
+
+ await this.Device.DeleteMessage(this.MessageId.Value);
+
+ this.MessageId = null;
+
+ if (this.KeyboardType == eKeyboardType.ReplyKeyboard)
+ {
+ await this.Device.Send("", new ReplyKeyboardRemove());
+ }
+
+ }
+
+ }
+
+
+}
diff --git a/TelegramBotBase/Enums/eKeyboardType.cs b/TelegramBotBase/Enums/eKeyboardType.cs
new file mode 100644
index 0000000..3cd255e
--- /dev/null
+++ b/TelegramBotBase/Enums/eKeyboardType.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TelegramBotBase.Enums
+{
+ public enum eKeyboardType
+ {
+ ///
+ /// Uses a ReplyKeyboardMarkup
+ ///
+ ReplyKeyboard = 0,
+
+ ///
+ /// Uses a InlineKeyboardMakup
+ ///
+ InlineKeyBoard = 1
+
+ }
+}
diff --git a/TelegramBotBase/Form/ButtonBase.cs b/TelegramBotBase/Form/ButtonBase.cs
index 67d193a..303a9d1 100644
--- a/TelegramBotBase/Form/ButtonBase.cs
+++ b/TelegramBotBase/Form/ButtonBase.cs
@@ -48,5 +48,17 @@ namespace TelegramBotBase.Form
}
+ public KeyboardButton ToKeyboardButton(ButtonForm form)
+ {
+ //String id = (form.DependencyControl != null ? form.DependencyControl.ControlID + "_" : "");
+ if (this.Url == null)
+ {
+ return new KeyboardButton(this.Text);
+ }
+
+ return new KeyboardButton(this.Text);
+
+ }
+
}
}
diff --git a/TelegramBotBase/Form/ButtonForm.cs b/TelegramBotBase/Form/ButtonForm.cs
index 7fe1df7..6fe043d 100644
--- a/TelegramBotBase/Form/ButtonForm.cs
+++ b/TelegramBotBase/Form/ButtonForm.cs
@@ -60,6 +60,14 @@ namespace TelegramBotBase.Form
return splitted;
}
+ public int Count
+ {
+ get
+ {
+ return this.Buttons.Select(a => a.ToArray()).Aggregate((a, b) => a.Union(b).ToArray()).Length;
+ }
+ }
+
///
/// Add buttons splitted in the amount of columns (i.e. 2 per row...)
///
@@ -75,19 +83,41 @@ namespace TelegramBotBase.Form
}
}
- public InlineKeyboardButton[][] ToArray()
+ public List ToList()
+ {
+ return this.Buttons.Aggregate((a, b) => a.Union(b).ToList());
+ }
+
+ public InlineKeyboardButton[][] ToInlineButtonArray()
{
var ikb = this.Buttons.Select(a => a.Select(b => b.ToInlineButton(this)).ToArray()).ToArray();
return ikb;
}
+ public KeyboardButton[][] ToReplyButtonArray()
+ {
+ var ikb = this.Buttons.Select(a => a.Select(b => b.ToKeyboardButton(this)).ToArray()).ToArray();
+
+ return ikb;
+ }
+
public static implicit operator InlineKeyboardMarkup(ButtonForm form)
{
if (form == null)
return null;
- InlineKeyboardMarkup ikm = new InlineKeyboardMarkup(form.ToArray());
+ InlineKeyboardMarkup ikm = new InlineKeyboardMarkup(form.ToInlineButtonArray());
+
+ return ikm;
+ }
+
+ public static implicit operator ReplyKeyboardMarkup(ButtonForm form)
+ {
+ if (form == null)
+ return null;
+
+ ReplyKeyboardMarkup ikm = new ReplyKeyboardMarkup(form.ToReplyButtonArray());
return ikm;
}