很多文本框,如何管理? MVVM WPF

时间:2015-08-13 04:43:44

标签: wpf mvvm textbox

我写了一些App,输入64字节用于通过某种通信标准发送。应用必须在每个文本框中有一个字节,所以我需要64个文本框。这意味着我必须制作64" NotifyPropertyChanged" getter / setter函数。或者有更好的方法吗?

如果没有更好的方法,如何管理所有这些功能?仅将此64个函数粘贴到特殊类文件中并连接到我的viewmodel?以及如何连接它?例如或其他什么?

总的来说,我需要64个文本框用于发送,然后还需要64个(文本块)用于接收消息。是可以在一个文本框中创建所有内容,但我不在此处做出决定:)

我还需要将字符inmptt限制为文本框 - 0-9和A-F。

我是MVVM和WPF的新手很抱歉,如果这是一个愚蠢的问题。如有任何其他问题,请询问。

2 个答案:

答案 0 :(得分:2)

Bindings支持数组,因此只需在视图模型中添加一个数组:

    public class MyViewModel
    {
        private int[] _Vals = new int[64];
        public int[] Vals { get { return this._Vals; } }
    }

并将每个文本框绑定到XAML中的元素:

<StackPanel Orientation="Vertical">
    <TextBox Text="{Binding Vals[0], UpdateSourceTrigger=PropertyChanged}" />
    <TextBox Text="{Binding Vals[1], UpdateSourceTrigger=PropertyChanged}" />
    <TextBox Text="{Binding Vals[2], UpdateSourceTrigger=PropertyChanged}" />
    <TextBox Text="{Binding Vals[3], UpdateSourceTrigger=PropertyChanged}" />
    ... etc ...
</StackPanel>

答案 1 :(得分:1)

考虑为一个字节(包含INotifyPropertyChanged的实现)创建一个ViewModel,并将64个实例添加到集合中。

然后你可以使用ItemsControl来显示TextBoxes并使用该集合来获取所有字节。

要限制文本框仅允许十六进制值,您可以使用ValueConverter的组合并处理文本框上的keydown。

public partial class MainWindow : Window
{
    private const int numberOfBytes = 64;
    private NumbersViewmodel numbers = new NumbersViewmodel(numberOfBytes);
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = numbers;
    }

}

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
}

public class NumbersViewmodel : ViewModelBase
{
    private ObservableCollection<NumberViewModel> numbers;

    public ObservableCollection<NumberViewModel> Numbers
    {
        get { return numbers; }
        set
        {
            if (numbers != value)
            {
                numbers = value;
                OnPropertyChanged("Numbers");
            }
        }
    }

    public ICommand SendNumbers
    {
        get;
        private set;
    }

    public NumbersViewmodel(int numberOfNumbers)
    {
        sendNumbers = new SimpleCommand(SendNumbersExecuted);
        this.Numbers = new ObservableCollection<NumberViewModel>();
        for (int i = 0; i < numberOfNumbers; i++)
        {
            this.Numbers.Add(new NumberViewModel());
        }
    }

    private void SendNumbersExecuted()
    {
        ///DoSomethingWith(Numbers);
    }
}

public class NumberViewModel : ViewModelBase
{
    private byte number;

    public byte Number
    {
        get { return number; }
        set
        {
            if (number != value)
            {
                number = value; 
                OnPropertyChanged("Number");
            }
        }
    }
}

public class SimpleCommand : ICommand
{
    private Action execute;
    public SimpleCommand(Action execute)
    {
        this.execute = execute;
    }
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        if (execute != null && CanExecute(parameter))
        {
            execute();
        }
    }
}

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <ScrollViewer>
        <ItemsControl ItemsSource="{Binding Numbers}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Number}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
    <Button Grid.Row="1"
            Command="{Binding SendBytes}">Send the bytes</Button>

</Grid>