【问题标题】:How to create buttons/shorcuts dynamically in XAML/C#如何在 XAML/C# 中动态创建按钮/快捷方式
【发布时间】:2018-08-29 11:09:18
【问题描述】:

我想创建一个应用程序,用户可以在其中输入文件的快捷方式。我知道如何在编译时在代码中创建按钮,但我不知道如何创建名称和点击事件将是动态的动态按钮。

创建如下图所示的内容有多难?这在 C#/WPF/XAML 中是否可行?

逻辑是什么?

仅供参考 - 我不需要帮助保存按钮对象,为此我将使用 JSON。

【问题讨论】:

  • “创建如下图所示的内容有多难?”比较简单。 “这在 C#/WPF/XAML 中是否可行?”当然。 “这会是什么逻辑?” ItemsControl 绑定到 ObservableCollection
  • 并使用模板。

标签: c# wpf xaml


【解决方案1】:

你应该创建一个ItemsControl 来显示你想要的,这可能是一种方法:

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

您应该使用文件名、要在按钮中显示的内容和命令创建一个新的(如果尚未创建)类。并且在初始化视图时,创建一个“链接”对象列表。

所有的命令都是一样的,只要用通用的方式声明它就可以打开你放在CommandParameter中的文件


现在我知道您正在使用 MVVM,我将尝试将我的答案重点扩大到这一点。

你需要一个我会称之为FileLink的课程。 FileLink 至少有 3 个属性:

  • 公共字符串 WhatYouWantToShow - 这将是您按钮的内容
  • public ICommand YourCommand - 这将有一个DelegateCommand&lt;string&gt;,它将是“做”事情的人。对于您创建的每个项目,此命令都是相同的。您只需要一个,因为您将使用该参数来执行/打开一个或另一个文件。
  • public string YourFileName - 这将是您执行命令方法所需的字符串。我猜这将是一个路径或文件名。

现在我们已经创建了这个类,在初始化第三个视图时,即带有按钮的视图,您将拥有一个ObservableCollectionproperty,我称之为YourListOfLinkObject,属于FileLinkobjects。在那里,您必须添加从数据库中获得的尽可能多的 FileLink 对象,它们将被显示出来。

如果您需要更改它们的显示方式,您只需修改DataTemplate

如果有什么我没能再次解释,或者你想让我更进一步,请告诉我 :)

【讨论】:

  • 您介意检查一下您的代码吗?我是否正确地说YourListOfLinkObject 将绑定到 ObservableCollection,WhateverYouWantToShow 绑定到按钮名称的属性,YourCommand 绑定到单击事件属性?我不确定YourFileName 将绑定到什么。你能详细说明一下吗?谢谢。
  • WhateverYouWantToShow 将显示给用户,而不是“Button1”或“Button2”。 YourFileName 我的意思是你需要用什么来打开/执行你想让你的按钮做的事情。如果您需要打开文件的路径,YourFileName 将是一个类似“C:\XXXX\XXXX”的字符串。对不起,我没有解释自己:P
  • @ Juan Carlos Rodriguez- 我不会骗你的,我对 YourCommandYourFileName 的 ViewModel 中的绑定和逻辑仍然有些困惑。
  • 检查一下:D
【解决方案2】:

这是可能且简单的。您将控件添加到容器并将容器添加到主窗体。点击事件只是在代码中定义(实际上你在开发时就知道——也许你应该改用用户控件)。 下面是一些部分代码,几年前在现实世界的 Silverlight 应用程序中做了类似的事情来给出这个想法:

 ...
 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);
    }

【讨论】:

  • 恕我直言,如果您可以在 XAML 中简单地对其进行编码而无需任何代码,那么代码太多了。
  • @JuanCarlosRodriguez,如果您喜欢编写 XMLish,为什么不呢?我更喜欢在代码中使用 XAML,因为他们杀死了 Silverlight - 学会了不以艰难的方式信任基于 MS 的技术。我只在运行时拥有所有这些。
  • 因为 UI 的任何更改都会变得更加困难......另外,如果您使用过 StackPanels,您可能知道他们在某些情况下无法正确管理自己的空间
  • 我看不到这段代码将如何处理从列表中的任何索引动态添加或删除的项目
  • @Ash,正如我所说,这是部分代码。你可以提供一个完整的,而不是对其他人投反对票。
猜你喜欢
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-23
相关资源
最近更新 更多