【问题标题】:Accessing Grid.Children.Add in MVVM (WPF)在 MVVM (WPF) 中访问 Grid.Children.Add
【发布时间】:2016-08-31 07:02:21
【问题描述】:

所以我有这样的想法,在一个网格中添加几个按钮,然后排列它们,添加的按钮数量与我输入的数字有关。一切正常,直到我尝试让它在 MVVM 下工作。

在 MainWindow.xaml.cs 中工作的代码:

 private void Button_Click(object sender, RoutedEventArgs e)
    {
        int i = 0, j = 0;
        Brush[] bs = { Brushes.BurlyWood, Brushes.Honeydew };

        for (i = 0; i < 3; i++)
        {
            for (j = 0; j < 3; j++)
            {
                Button btn = new Button();
                btn.Height = 50;
                btn.Width=50;
                btn.SetValue(Grid.RowProperty, i);
                btn.SetValue(Grid.ColumnProperty, j);
                if ((i + j) % 2 == 0)
                {
                   btn.Background=bs[0];
                }
                else btn.Background = bs[1];

                GameGrid.Children.Add(btn);
            }
        }
    }

所以基本上,我按下一个按钮,它会添加 3x3 的按钮,颜色很好,分布得当。但后来我到了 MVVM:

private void ButtonClickCommand()
    {
        RowCount = GridNumber;
        ColumnCount=GridNumber;
        int i = 0, j = 0;

        Brush[] bs = { Brushes.BurlyWood, Brushes.Honeydew };

        for (i = 0; i < GridNumber; i++)
        {
            for (j = 0; j < GridNumber; j++)
            {
                Button btn = new Button();
                btn.Height = 50;
                btn.Width = 50;
               // btn.Command = StartCommand; Ill add that later
                btn.SetValue(Grid.RowProperty, i);
                btn.SetValue(Grid.ColumnProperty, j);
                if ((i + j) % 2 == 0)
                {
                    btn.Background = bs[0];
                }
                else btn.Background = bs[1];

                somebuttonlist.Add(btn);
            }
        }

    }

这里我有一个按钮列表,它应该接受新创建的按钮,然后将它们传输到网格。按钮列表代码:

 private List<Button> _bslist = new List<Button>();
    public List<Button> somebuttonlist
    {
        get
        {
            return _bslist;
        }
        set
        {
            _bslist = value;
            NotifyPropertyChanged();

        }
    }

还有xaml代码:

 <ItemsControl ItemsSource="{Binding somebuttonlist}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate> 
                <Grid Name="GameGrid" Visibility="{Binding GameVis}"
                vm:GridHelpers.RowCount="{Binding RowCount}"
                vm:GridHelpers.ColumnCount="{Binding ColumnCount}">
                </Grid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>

不要介意所有绑定,当我使用非 MVVM 格式时,它们可以正常工作。 那么如何正确地将工作代码转移到视图模型中呢?有没有办法相应地访问孩子?

【问题讨论】:

    标签: c# wpf xaml mvvm


    【解决方案1】:

    看起来您正在绑定到List,它不会在插入新记录或删除任何记录时发出通知。您拥有的NotifyPropertyChanged() 仅在对该列表的引用被修改时才会启动,例如,将其设置为new List() 或不同的List。尝试将其更改为 ObservableCollection,它会在集合中的记录数被修改时发送 event

    【讨论】:

      【解决方案2】:

      这不是 MVVM 的正确处理方式。您现在要做的是将可视化代码拉入您的 ViewModel。理想情况下,ViewModel 应该放在一个单独的项目中,而不需要对视觉内容进行任何引用。这样,引用 Button 将导致代码损坏,除非您添加对 System.Windows.Controls 的引用,这会提醒您做错了事情。

      您正在尝试做的事情以纯 MVVM 方式是可行的,但会产生更多代码,如果您还没有掌握 MVVM,这也会让您感到困惑。另请注意,在现实生活中,为复杂的场景保留一些代码是可以接受的。为此,您只需创建一个自定义控件来封装逻辑背后的所有代码。

      在您的情况下,不错的解决方案可以是自定义控件,它封装 Grid 和用按钮填充它的逻辑。您还添加了行和列的依赖属性,因此您可以在 XAML 中绑定到它们,并定义单击按钮时调用的命令。这可能是一个很好的例子:How to create bindable commands in Custom control?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-24
        • 1970-01-01
        • 2010-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多