WPF项目控制网格

时间:2015-03-25 19:51:45

标签: c# wpf mvvm

我正在尝试制作包含一些按钮(1,4,8)的网格。

<Window x:Class="WpfApplication9.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid >
    <Grid.RowDefinitions>
        <RowDefinition Height="20"></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
    </Grid.ColumnDefinitions>
    <!--<Grid Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Grid.Column="0"></Button>
        <Button Grid.Row="0" Grid.Column="1"></Button>
        <Button Grid.Row="1" Grid.Column="0"></Button>
        <Button Grid.Row="1" Grid.Column="1"></Button>
    </Grid>-->
    <ItemsControl ItemsSource="{Binding TheList}" x:Name="MyGrid" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="Auto" Grid.Row="1">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                    </Grid.RowDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
    <StackPanel Orientation="Horizontal">
        <Button Command="{Binding One}">1</Button>
        <Button Command="{Binding Four}">4</Button>
        <Button Command="{Binding Eight}">8</Button>
    </StackPanel>
</Grid>

代码:

using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfApplication9
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
/// 

public partial class MainWindow : Window
{
    public class ViewModelTest : INotifyPropertyChanged
    {
        private ObservableCollection<Button> theList;
        public ObservableCollection<Button> TheList
        {
            get { return theList; }
            set { theList = value; NotifyPropertyChanged("TheList"); }
        }
        public ViewModelTest()
        {
            One = new RelayCommand(() => OneButton());
            Four = new RelayCommand(() => FourButton());
            Eight = new RelayCommand(() => EightButton());



            //TheList.Clear();
            //for (int i = 0; i < 4; i++)
            //{
            //    System.Windows.Controls.Button newBtn = new Button();
            //    newBtn.Content = i.ToString();
            //    newBtn.Name = "Button" + i.ToString();
            //    TheList.Add(newBtn);
            //}
        }
        public ICommand One { get; set; }
        public ICommand Four { get; set; }
        public ICommand Eight { get; set; }


        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        public void OneButton()
        {
            TheList = new ObservableCollection<Button>();                
            for (int i = 0; i < 1; i++)
            {
                Button btn = new Button();
                System.Windows.Controls.Button newBtn = new Button();
                newBtn.Content = i.ToString();
                newBtn.Name = "Button" + i.ToString();
                TheList.Add(newBtn);
            }
        }
        public void FourButton()
        {
            TheList = new ObservableCollection<Button>();
            for (int i = 0; i < 4; i++)
            {
                Button btn = new Button();
                System.Windows.Controls.Button newBtn = new Button();
                newBtn.Content = i.ToString();
                newBtn.Name = "Button" + i.ToString();
                TheList.Add(newBtn);
            }

            //MyGrid.Children.Clear();
            //MyGrid.ColumnDefinitions.Clear();
            //MyGrid.RowDefinitions.Clear();
            //MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
            //MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
            //MyGrid.RowDefinitions.Add(new RowDefinition());
            //MyGrid.RowDefinitions.Add(new RowDefinition());
            //for (int row =0;row<MyGrid.ColumnDefinitions.Count;row++)
            //{
            //    for (int column=0;column<MyGrid.ColumnDefinitions.Count;column++)
            //    {
            //            System.Windows.Controls.Button newBtn = new Button();
            //            newBtn.Content = row.ToString() + column.ToString();
            //            newBtn.Name = "Button" + row.ToString()+column.ToString();
            //            newBtn.SetValue(Grid.ColumnProperty,column);
            //            newBtn.SetValue(Grid.RowProperty, row);
            //            MyGrid.Children.Add(newBtn);
            //    }
            //}
        }
        public void EightButton()
        {
            TheList = new ObservableCollection<Button>();
            for (int i = 0; i < 8; i++)
            {
                Button btn = new Button();
                System.Windows.Controls.Button newBtn = new Button();
                newBtn.Content = i.ToString();
                newBtn.Name = "Button" + i.ToString();
                TheList.Add(newBtn);
            }
            //MyGrid.Children.Clear();
            //MyGrid.ColumnDefinitions.Clear();
            //MyGrid.RowDefinitions.Clear();
            //MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
            //MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
            //MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
            //MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
            //MyGrid.RowDefinitions.Add(new RowDefinition());
            //MyGrid.RowDefinitions.Add(new RowDefinition());
            //for (int row = 0; row < MyGrid.ColumnDefinitions.Count; row++)
            //{
            //    for (int column = 0; column < MyGrid.ColumnDefinitions.Count; column++)
            //    {
            //        System.Windows.Controls.Button newBtn = new Button();
            //        newBtn.Content = row.ToString() + column.ToString();
            //        newBtn.Name = "Button" + row.ToString() + column.ToString();
            //        newBtn.SetValue(Grid.ColumnProperty, column);
            //        newBtn.SetValue(Grid.RowProperty, row);
            //        MyGrid.Children.Add(newBtn);
            //    }
            //}
        }
    }
    public MainWindow()
    {

        DataContext = new ViewModelTest();
        InitializeComponent();

    }
}

但是显示有问题。在这种情况下,如何动态地在itemcontrol中创建新的列和行。

1 个答案:

答案 0 :(得分:0)

好的,从哪里开始......
你在这里遇到了几个问题。

  1. TheList是一个ObservableCollection,因此不需要在TheList属性中使用'NotifyPropertyChanged'。并且不需要theList成员变量。只需将以下内容用于您的财产:

    public ObservableCollection TheList {get;组; }

  2. 但是,在您的代码后面,在单击其中一个按钮之前,“TheList”不会被初始化。因此,你的XAML绑定到一个null对象,所以几乎不绑定任何东西,无论你在绑定之后将'TheList'更改为什么,你仍然绑定为null。要解决此问题,请确保在InitializeComponents()调用之前在构造函数中初始化TheList。将构造函数更改为以下内容:

    public MainWindow() { TheList = new ObservableCollection<Button>(); DataContext = new ViewModelTest(); InitializeComponent(); }

  3. 此外,您设置TheList = new ObservableCollection<Button>()的所有位置只是将指针更改为其他位置,因此Binding再次被破坏。不要重新初始化TheList,只需执行TheList.Clear();,然后使用TheList.Add(newBtn);

    将按钮添加到TheList
    1. 所以,看起来你有一堆没有高度的RowDefinitions,我猜这些只是占位符?您可以将网格命名为x:Name="MyInternalGrid",然后当您添加到TheList时,将行添加到MyInternalGrid也是如此。因此,当致电TheList.Clear();时,也可以通过调用MyInternalGrid.RowDefinitions.Clear();来清除您的gridRows。然后,每当您致电TheList.Add(newBtn);时,请使用MyInternalGrid.RowDefinitions.Add(new RowDefinition{Height=20});向您的网格添加另一行。执行此操作时,请确保将正确的行分配给newBtn。在将Grid.SetRow(newBtn, MyInternalGrid.RowDefinitions.Count);添加到newBtn之前TheList。这就是我的意思,改变你的方法来模仿下面重构的EightButton()方法:

      public void EightButton() { TheList.Clear(); MyInternalGrid.RowDefinitions.Clear(); for (int i = 0; i < 8; i++) { Button newBtn = new Button(); newBtn.Content = i.ToString(); newBtn.Name = "Button" + i.ToString(); Grid.SetRow(newBtn, MyInternalGrid.RowDefinitions.Count);
      MyInternalGrid.RowDefinitions.Add(new RowDefinition{Height=20}); TheList.Add(newBtn); } }

    2. 或者,您可能只是不想担心所有网格行,并在<StackPanel>中添加<Grid>并动态添加所有按钮<StackPanel>。首先清除堆栈面板MyStackPanel.Children.Clear();,然后在循环中添加新按钮MyStackPanel.Children.Add(newBtn);

      首页其中一些有帮助。