作為 XAML/MVVM 的完整初學者,我想請求一些有關實作 24x14 字母螢屏的幫助。
我認為 XAML 實作非常簡單,例如
<Grid x:Name="ScreenGrid"
RowDefinitions="*, *, *, *, *, *, *, *, *, *, *, *, *, *"
ColumnDefinitions="*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*"/>
然而,我正在努力解決的是資料系結。
我想寫一個類似“UpdateScreen()”的方法,用資料填充那個網格
- 每個網格單元有 1 個字母
- 每個字母都有顏色(紅色、綠色……)
- 每個字母或大或小
我當前的 ViewModel 看起來像這樣(在 Microsoft.Toolkit.Mvvm 的幫助下):
public partial class ScreenViewModel : ObservableObject
{
[ObservableProperty]
private ScreenText[] _screen;
//ScreenText consists of char value, Color color, bool isBig
[ICommand]
private void ButtonPressed(AppButton button)
{
System.Diagnostics.Debug.WriteLine($"Button {button} was pressed");
}
private void UpdateScreen()
{
[.?.]
}
}
它應該與應用程式的實際邏輯進行通信,生成一個 ScreenText[],然后傳遞回 ViewModel。
如何將它連接到 ScreenGrid?
謝謝你的幫助。
uj5u.com熱心網友回復:
這是一種以編程方式將單元格添加為網格子項的方法,每個單元格都系結到視圖模型中串列的一個元素。
鑒于:
public class ScreenText
{
// I think binding to xaml requires string, not char.
public string Value {
get => value.ToString();
}
...
}
和 ScreenViewModel.cs:
public class ScreenViewModel : ObservableObject
{
// List or ObservableCollection (not Array) usually used for Xamarin Forms.
public ObservableCollection<ScreenText> Texts { get; } = new ObservableCollection<ScreenText>();
...
}
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ManipulateGridChildren.MainPage">
<Grid x:Name="ScreenGrid"
RowDefinitions="*, *, *, *, *, *, *, *, *, *, *, *, *, *"
ColumnDefinitions="*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*"/>
</ContentPage>
MainPage.xaml.cs:
using System.Collections.Generic;
using Xamarin.Forms;
namespace ManipulateGridChildren
{
public partial class MainPage : ContentPage
{
const int NRows = 14;
static int NColumns = 24;
public MainPage(ScreenViewModel vm)
{
InitializeComponent();
// So you can access from any method.
VM = vm;
AddCells(vm);
BindingContext = vm;
}
private ScreenViewModel VM;
// Used a dictionary, so can add cells in any order.
private Dictionary<int, Label> cells = new Dictionary<int, Label>();
private void AddCells(ScreenViewModel vm)
{
// Grid rows and columns are numbered from "0".
for (int row = 0; row < NRows; row ) {
for (int column = 0; column < NColumns; column ) {
var cell = AddCell(row, column, vm);
}
}
}
private Label AddCell(int row, int column, ScreenViewModel vm)
{
var index = CellKey(row, column);
var cell = new Label();
// NOTE: I think "Value" has to be a "string" not a "char".
cell.SetBinding(TextProperty, $"Texts[{index}].Value");
cell.TextColor = Color.Black;
cell.BackgroundColor = Color.White;
cell.HorizontalTextAlignment = TextAlignment.Center;
cell.VerticalTextAlignment = TextAlignment.Center;
ScreenGrid.Children.Add(cell, column, row);
// This dictionary makes it easier to access individual cells later.
cells[index] = cell;
return cell;
}
// Assign unique key to each cell.
private int CellKey(int row, int column)
{
return row * NColumns column;
}
// Can use this to access an individual cell later.
// For example, you might change some property on that cell.
private Label GetCell(int row, int column)
{
return cell[CellKey(row, column)];
}
}
選擇:
對于不使用視圖模型的任何人,請在此處查看我的答案。
uj5u.com熱心網友回復:
我的解決方案(最小示例)如下所示:
在 XAML 中,網格的定義如下
<Grid x:Name="ScreenGrid"
RowDefinitions="*, *, *, *, *, *, *, *, *, *, *, *, *, *"
ColumnDefinitions="*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*"/>
ViewModel 看起來像這樣(在Toolkit.Mvvm的幫助下):
public partial class ScreenViewModel : ObservableObject
{
const int LINES = 14;
public ObservableCollection<ScreenText> Screen { get; } = new ObservableCollection<ScreenText>();
public ScreenViewModel()
{
for (int i = 0; i < LINES; i )
{
Screen.Add(new ScreenText());
}
}
[ICommand]
private void ButtonPressed(AppButton button)
{
System.Diagnostics.Debug.WriteLine($"Button {button} was pressed");
//Do some business logic and manipulate the screen
OnPropertyChanged(nameof(Screen));
}
}
最后是 MainPage.Xaml.cs:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
//Setup Screen
AddScreenCells();
}
private void AddScreenCells()
{
for (int row = 0; row < ScreenGrid.RowDefinitions.Count; row )
{
for (int col = 0; col < ScreenGrid.ColumnDefinitions.Count; col )
{
Label label = new Label();
label.SetBinding(Label.TextProperty, $"{nameof(ScreenViewModel.Screen)}[{row}].{nameof(ScreenText.Letters)}[{col}]");
ScreenGrid.Add(label, col, row);
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/478209.html
