fs_tigre
fs_tigre

Reputation: 10738

How to create buttons/shorcuts dynamically in XAML/C#

I want to create an application where the user can enter shortcuts to files. I know how to create buttons in code at compile time but I have no idea how to create dynamic buttons where the name and the click event are going to be dynamic.

How hard would it be to create something like the image below? Is that even possible in C#/WPF/XAML?

What would be the logic?

FYI - I don't need help with saving the buttons objects, for this I will be using JSON.

enter image description here

Upvotes: 0

Views: 547

Answers (2)

Juan Carlos Rodriguez
Juan Carlos Rodriguez

Reputation: 784

You should create an ItemsControl to show what you want, this could be an approach:

<ItemsControl 
       ItemsSource="{Binding YourListOfLinkObject}">
       <ItemsControl.ItemTemplate>
          <DataTemplate>                  
                  <Button Content="{Binding WhateverYouWantToShow}"
                          Command="{Binding YourCommand} " 
                          CommandParameter="{Binding YourFileName}"/>                  
          </DataTemplate>
       </ItemsControl.ItemTemplate>   
</ItemsControl>

You should create a new (if it's not already created) class with the name of the file, the content you want to show in the button and your command. And when initializing the view, create a list of "Link" object.

The command will be the same for all of them, just declare it in a generic way to open the file you put in the CommandParameter


Now that I know you are using MVVM I will try to expand my answer focus on that.

You need a class that I will call FileLink. FileLink will have, at least, 3 properties:

  • public string WhateverYouWantToShow - This will be the content of your button
  • public ICommand YourCommand - This will have a DelegateCommand<string> that will be the one who "does" things. This command will be the same for every item you create. You just need one because you will use the parameter to execute/open one file or another.
  • public string YourFileName - This will be the string you need to execute your command method. I guess it will be a path or a file name.

Now that we have this class created, when initializing the third view, the one with the buttons, you will have an ObservableCollectionproperty, what I called YourListOfLinkObject, of FileLinkobjects. There you will have to add as many FileLink objects as you got from the database and they will be displayed.

If you need to change the way they are shown you just need to modify the DataTemplate.

If there's something I failed to explain again or you want me to go further just let me know :)

Upvotes: 3

Cetin Basoz
Cetin Basoz

Reputation: 23797

It is possible and simple. You add controls to your container and add container to main form. Click event is simply defined in code (which actually you know at dev time - probably you should instead use user controls). Below is some partial code, doing a similar thing in a real world Silverlight application from years ago to give the idea:

 ...
 sp.Children.Add(p);

        foreach (var slot in group)
        {
            var color = colors[(int)slot.State];
            var name = String.Format("W{0}", slot.When.ToString("yyyyMMddHHmm"));

            Rectangle rect = new Rectangle
            {
                Name = name,
                Width = rectWidth,
                Height = rectWidth,
                Margin = new Thickness(rectMargin),
                Stroke = new SolidColorBrush(slot.State == Availability.Booked ? Colors.White : Colors.Black),
                StrokeThickness = 1,
                Fill = new SolidColorBrush(color),
                RadiusX = 2,
                RadiusY = 2,
                Cursor = (slot.State == Availability.Booked ? Cursors.Arrow : Cursors.Hand)
            };
            if (slot.State != Availability.Booked)
            {
                rect.Effect = new DropShadowEffect(); //myDropShadowEffect,
            }
            if (slot.State != Availability.Booked)
            {
                rect.MouseLeftButtonDown += new MouseButtonEventHandler(rect_MouseLeftButtonDown);
                ToolTipService.SetToolTip(rect, slot.When.ToString("MMM dd,yyyy dddd hh:mm tt"));
            }
            sp.Children.Add(rect);
        }
        b.Child = sp;
        contentStackPanel.Children.Add(b);
    }

Upvotes: 0

Related Questions