在哪里放置代码以在视图中创建大量按钮?

时间:2015-10-10 05:29:00

标签: c# wpf user-interface mvvm

我正在学习MVVM。到目前为止,我有一个窗口(没有MVVM),我在构造函数后面的代码中调用CreateLetterButtons()方法,该方法为StackPanel中字母表中的每个字母创建按钮。我这样做是因为它比在XAML中创建所有这些按钮更容易 - 特别是如果我想改变这些按钮的某些内容。

<script type = "text/javascript"> 
    var request_dict = {{request_dict|safe}};
 </script>

在此窗口中使用按钮输入文本(只是几个字母)而不是键盘。

现在我的问题:我应该将此代码保存在窗口后面的代码中吗?根据MVVM,我想这是正确的,因为这些按钮只是视图的一部分,用于在视图中输入文本。它们与任何底层数据(模型)没有关联,所以我猜这段代码不应该在视图模型中,对吗?

然后还有一个小问题:现在我的方法CreateLetterButtons()仅在我的应用程序运行并且窗口被加载时运行,所以我在设计视图中看不到这些按钮。但是如果我在ViewModel的构造函数中调用CreateLetterButtons()方法,则在执行ViewModel构造函数时会创建字母,即使在设计模式下也会发生。

我喜欢MVVM的想法,但我想知道我是否应该像对待法律那样对待它,或者更像是我不时会忽略的建议。我一个人工作,我不必考虑团队中有什么意义。

2 个答案:

答案 0 :(得分:3)

不要在后面的代码中创建UI元素。

在真正的MVVM方法中,您将使用ItemsControl来显示按钮的集合。然后,ItemsControl的ItemsSource属性绑定到视图模型类中的字符集合。在ItemTemplate中,Button的Content属性绑定到单个字符。

<ItemsControl ItemsSource="{Binding Letters}">
    <ItemsControl.DataContext>
        <local:LettersViewModel/>
    </ItemsControl.DataContext>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding}" MinWidth="20" Click="LetterButtonClick"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

后面的代码只是初始化视图模型并提供Button Click处理程序:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void LetterButtonClick(object sender, RoutedEventArgs e)
    {
        var button = (Button)sender;
        Trace.WriteLine("Clicked " + button.Content);
    }
}

public class LettersViewModel
{
    public LettersViewModel()
    {
        Letters = Enumerable.Range('A', 'Z' - 'A' + 1).Select(l => (char)l);
    }

    public IEnumerable<char> Letters { get; private set; }
}

如果没有明确的VM类,可能更简单的方法如下。它起作用,因为字符串也是IEnumerable<char>

<ItemsControl ItemsSource="ABCDEFGHIJKLMNOPQRSTUVWXYZ">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button MinWidth="20" Content="{Binding}" Click="LetterButtonClick"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

答案 1 :(得分:0)

在我看来,这是正确的视图,因此在视图模型之外。可绑定的按钮数据集合可以促进它,但在描述您的应用程序时没有必要。

至于设计时支持,请在后面的代码中调用构造函数中的createletterbuttons方法。这可能不是首选行为,因此您可以将其限制为仅在设计时运行。我使用来自nugget的mvvmlight库,它有一个静态的IsInDesignMode属性,你可以反对。

希望有所帮助。