You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Microsoft Silverlight在线文件存储系统动态生成按钮技术求助

Hey Daniel, let's work through this problem you're facing—generating dynamic buttons/links for user files on load is a super common scenario in Silverlight, and we've got two reliable ways to make it happen.

Approach 1: Dynamically Create Controls in C# Code-Behind

If you want a straightforward, quick implementation, you can create and add buttons directly in your C# code. Here's how:

Step 1: Add a Container in XAML

First, place a layout container (like StackPanel or WrapPanel) in your XAML to hold the dynamic buttons. Give it a name so you can reference it in code:

<StackPanel x:Name="fileContainer" Orientation="Vertical" Margin="10" />

Step 2: Generate Buttons in Code-Behind

In your page's code-behind, fetch the user's file list, loop through each file, create a button/hyperlink, and add it to the container:

// Assume you have a method that retrieves the user's files (e.g., List<FileInfo> userFiles)
private void LoadUserFiles()
{
    var userFiles = GetUserDirectoryFiles(); // Replace with your actual file retrieval logic

    foreach (var file in userFiles)
    {
        // Use HyperlinkButton for link-style UI, or Button for a standard button
        var fileLink = new HyperlinkButton();
        fileLink.Content = file.Name;
        fileLink.Tag = file; // Store the file object for easy access on click
        fileLink.Click += FileLink_Click;
        fileLink.Margin = new Thickness(0, 5, 0, 0); // Add spacing between items

        // Make sure we're on the UI thread (critical if fetching files asynchronously)
        Dispatcher.BeginInvoke(() => fileContainer.Children.Add(fileLink));
    }
}

// Handle the button click event
private void FileLink_Click(object sender, RoutedEventArgs e)
{
    var clickedLink = sender as HyperlinkButton;
    var selectedFile = clickedLink.Tag as FileInfo;

    // Add your file action logic here (e.g., download, open preview)
    MessageBox.Show($"You selected: {selectedFile.Name}");
}

For a more scalable, maintainable solution (aligned with OOP and MVVM principles), use ItemsControl to bind your file data to the UI. This way, you don't manually manipulate controls—your data drives the UI.

Step 1: Create a File View Model

First, define a simple view model class to represent your files (this is the OOP part):

public class FileViewModel : INotifyPropertyChanged
{
    private string _fileName;
    public string FileName
    {
        get => _fileName;
        set
        {
            _fileName = value;
            OnPropertyChanged(nameof(FileName));
        }
    }

    // Add other properties like file size, path, etc., as needed
    public ICommand FileActionCommand { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

// Simple RelayCommand implementation (Silverlight doesn't include this by default)
public class RelayCommand : ICommand
{
    private readonly Action _execute;
    public RelayCommand(Action execute) => _execute = execute;
    public bool CanExecute(object parameter) => true;
    public void Execute(object parameter) => _execute();
    public event EventHandler CanExecuteChanged;
}

Step 2: Set Up Data Collection in Your Page

In your page's code-behind (or view model if using MVVM), create an ObservableCollection to hold your file view models. This collection automatically updates the UI when items are added/removed:

public ObservableCollection<FileViewModel> UserFiles { get; set; }

public MainPage()
{
    InitializeComponent();
    UserFiles = new ObservableCollection<FileViewModel>();
    LoadUserFilesToCollection();
    this.DataContext = this; // Bind the page to itself (or use a separate view model)
}

private void LoadUserFilesToCollection()
{
    var userFiles = GetUserDirectoryFiles();

    foreach (var file in userFiles)
    {
        UserFiles.Add(new FileViewModel
        {
            FileName = file.Name,
            FileActionCommand = new RelayCommand(() => HandleFileAction(file))
        });
    }
}

private void HandleFileAction(FileInfo file)
{
    // Your file logic here
    MessageBox.Show($"Processing file: {file.Name}");
}

Step 3: Bind to ItemsControl in XAML

Finally, use ItemsControl in XAML to render each file as a button/hyperlink. You can customize the layout and template easily:

<ItemsControl ItemsSource="{Binding UserFiles}">
    <!-- Define how each file item looks -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <HyperlinkButton Content="{Binding FileName}"
                             Command="{Binding FileActionCommand}"
                             Margin="5"
                             FontSize="12"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

    <!-- Optional: Change layout to horizontal wrapping instead of vertical -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

Key Notes

  • UI Thread Warning: If you're fetching files asynchronously (e.g., from a web service), always use Dispatcher.BeginInvoke when modifying UI elements (like adding buttons to the container).
  • Choose Control Type: Use HyperlinkButton for a link-like appearance, or Button for a standard button—both work with either approach.
  • Scalability: The ItemsControl method is better for long-term maintenance, especially if you plan to add features like file filtering, sorting, or dynamic updates to the file list.

Either of these methods should solve your problem. Start with the code-behind approach for a quick fix, or go with the data-bound ItemsControl method for a more robust, OOP-aligned solution.

内容的提问来源于stack exchange,提问作者Daniel Stewart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:46:57