0

I try to create custom keyboard for telegram bot. Use the solution by AmatuerDev: create dynamic Keyboard telegram bot in c# , MrRoundRobin API and it looks like this :

button in row

How to place a button in a column?

Thanks You!

P.S. Source code:

private static InlineKeyboardButton[][] GetInlineKeyboard(string [] 
stringArray)
{
var keyboardInline = new InlineKeyboardButton[1][];
var keyboardButtons = new InlineKeyboardButton[stringArray.Length];
for (var i = 0; i < stringArray.Length; i++)
{
    keyboardButtons[i] = new InlineKeyboardButton
    {
        Text = stringArray[i],
        CallbackData = "Some Callback Data",
    };
}
keyboardInline[0] = keyboardButtons;
return keyboardInline;
}
Andrey
  • 3
  • 3

3 Answers3

2

Notes:

  1. Change return type for GetInlineKeyboard to InlineKeyboardMarkup instead of InlineKeyboardButton[][]
  2. Use explicit types instead of implicit (var)
  3. Use List<InlineKeyboardButton> instead of Array (InlineKeyboardButton[])
  4. Don't create buttons with same callback data
  5. Replace method parameters to take IDictionary<string, string> to get text and callback data

Every IEnumerable<InlineKeyboardButton> Is single row, This means you should pass list of rows.

You shouldn't use var keyboardInline = new InlineKeyboardButton[1][]; because this means only one row with buttons in this row!

There are two ways below:


Code you wants:

I don't suggest this code

private static InlineKeyboardButton[][] GetInlineKeyboard(string[] stringArray)
{
    var keyboardInline = new InlineKeyboardButton[stringArray.Length][];

    for (var i = 0; i < stringArray.Length; i++)
    {
        keyboardInline[i] = new InlineKeyboardButton[]
        {
            new InlineKeyboardButton
            {
                Text = stringArray[i],
                CallbackData = "Some Callback Data",
            };
        }
    }

    return keyboardInline;
}

Best way:

I suggest this code:

private static InlineKeyboardMarkup GetInlineKeyboard(IDictionary<string, string> buttonsData)
{
    // Rows Count
    int count = buttonsData.Length;

    // List of rows 
    // Every 'List<InlineKeyboardButton>' is row
    List<List<InlineKeyboardButton>> buttons = new List<List<InlineKeyboardButton>>(count);    

    for (int i = 0; i < count; i++)
    {
        // Add new row with one button capacity
        buttons.Add(new List<InlineKeyboardButton>(1)
        {
            // Add button to this row
            new InlineKeyboardButton
            {
                Text = buttonsData.Values.ElementAt(i),
                CallbackData = buttonsData.Keys.ElementAt(i),
            }
        });
    }
    
    return new InlineKeyboardMarkup(buttons);
}
Muaath
  • 579
  • 3
  • 19
  • 1
    Best way is not working :( Error CS1503 Argument 1: cannot convert from 'Telegram.Bot.Types.ReplyMarkups.InlineKeyboardButton[]' to 'System.Collections.Generic.List – Andrey Sep 24 '20 at 08:46
  • I followed the login provided in "Best Way" and managed to show inlineButtons one on top of the other. Reason for my vote up. Thanks Muaath for the solution – Simba Apr 02 '22 at 12:37
  • Your best way answer helped me - Jzk -@Muaath, I have answered with new approach which has a new method. – Abdush Samad Miah Jan 14 '23 at 10:18
0

I'm not sure if the code has massively changed as I haven't tried the above method(answered by Muaath), but this was the fix for me, inspiration from Muaath answer above:

public async Task<InlineKeyboardMarkup> GetInlineKeyboardMarkup(IReadOnlyList<SomeClassObject> someClassObject)
        {

            int count = someClassObject.Count;
            List<List<InlineKeyboardButton>> buttons = new List<List<InlineKeyboardButton>>(someClassObject.Count);

            for (int i = 0; i < count; i++)
            {
                // Add new row with one button capacity
                buttons.Add(new List<InlineKeyboardButton>(1)
                {
                      InlineKeyboardButton.WithCallbackData(text: $"{someClassObject[i].Title}", callbackData: $"{someClassObject[i].Id}"),
                });
            }

            return new InlineKeyboardMarkup(buttons);
        }

Note the difference is there is now a new method: InlineKeyboardButton.WithCallbackData()

As per documentation: https://telegrambots.github.io/book/2/reply-markup.html

Abdush Samad Miah
  • 186
  • 1
  • 8
  • 19
-1

You need to put each button in array. Reply markup: keyboard & inline keyboard