如何在 ViewModel 中使用数组? [英] How can I use an array in a ViewModel?

查看:24
本文介绍了如何在 ViewModel 中使用数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码现在看起来像这样,每条消息都有两行代码.代码有效,但如果我有例如 30 条消息,我可以给每个消息赋值,那么我将需要 60 行代码来声明所有内容:

string _msg1;字符串 _msg2;公共字符串 Msg1 { get =>_msg1;设置 =>SetProperty(ref _msg1, value);}公共字符串 Msg2 { get =>_msg2;设置 =>SetProperty(ref _msg2, value);}

在 C# 中,我分配给这些:

vm.Msg1 = "A";vm.Msg2 = "B";

在 XAML 中,我将 Text 绑定到 Msg1,将另一个 Text 绑定到 Msg2

有人能告诉我如何/如果我可以用数组来做这件事,这样我就可以像这样分配,希望这样数组的分配可以在两行而不是每条消息的两行中完成:

vm.Msg[0] = "A";vm.Msg[1] = "B";

供参考:

公共类 ObservableObject : INotifyPropertyChanged{protected virtual bool SetProperty(ref T backingStore,T 值,[CallerMemberName]string propertyName = "",操作 onChanged = null){if (EqualityComparer.Default.Equals(backingStore, value))返回假;backingStore = 值;onChanged?.Invoke();OnPropertyChanged(propertyName);返回真;}公共事件 PropertyChangedEventHandler PropertyChanged;protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = "") =>PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}

解决方案

您可以使用支持属性更改的

My code looks like this right now with two lines of code for each message. The code works but if I have for example 30 messages that I can each give values to then I will need to have 60 lines of code just to declare everything:

string _msg1;
string _msg2;
public string Msg1 { get => _msg1; set => SetProperty(ref _msg1, value); }
public string Msg2 { get => _msg2; set => SetProperty(ref _msg2, value); }

and in C# I assign to these:

vm.Msg1 = "A";
vm.Msg2 = "B"; 

and in the XAML I bind my Text to Msg1 and another Text to Msg2

Can someone tell me how / if I can do this with array so that I would assign like this and hopefully so the assignment of the array can just be done in two lines instead of 2 lines for every single message:

vm.Msg[0] = "A";
vm.Msg[1] = "B";

For reference:

public class ObservableObject : INotifyPropertyChanged
{

    protected virtual bool SetProperty<T>(
        ref T backingStore, T value,
        [CallerMemberName]string propertyName = "",
        Action onChanged = null)
    {
        if (EqualityComparer<T>.Default.Equals(backingStore, value))
            return false;

        backingStore = value;
        onChanged?.Invoke();
        OnPropertyChanged(propertyName);
        return true;
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = "") =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

}

解决方案

You can create a simple wrapper class with indexing that supports property change notification.

For example:

public class Messages : ObservableObject
{
    readonly IDictionary<int, string> _messages = new Dictionary<int, string>();

    [IndexerName("Item")] //not exactly needed as this is the default
    public string this[int index]
    {
        get
        {
            if (_messages.ContainsKey(index))
                return _messages[index];

//Uncomment this if you want exceptions for bad indexes
//#if DEBUG
//          throw new IndexOutOfRangeException();
//#else
            return null; //RELEASE: don't throw exception
//#endif
        }

        set
        {
            _messages[index] = value;
            OnPropertyChanged("Item[" + index + "]");
        }
    }
}

And, create a property in view model as:

private Messages _msg;
public Messages Msg
{
    get { return _msg ?? (_msg = new Messages()); }
    set { SetProperty(ref _msg, value); }
}

Now you can set or update values as:

vm.Msg[0] = "A";
vm.Msg[1] = "B";

Bindings in XAML will be same as:

<Label Text="{Binding Msg[0]}" />
<Label Text="{Binding Msg[1]}" />

Sample usage code

XAML

<StackLayout Margin="20">
    <Label Text="{Binding Msg[0]}" />
    <Label Text="{Binding Msg[1]}" />
    <Label Text="{Binding Msg[2]}" />
    <Label Text="{Binding Msg[3]}" />
    <Label Text="{Binding Msg[4]}" />

    <Button Text="Trigger update" Command="{Binding UpdateMessage}" />
</StackLayout>

Code-behind, view-model

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();

        var viewModel = new MainViewModel();

        viewModel.Msg[0] = "Original message 1";
        viewModel.Msg[1] = "Original message 2";
        viewModel.Msg[2] = "Original message 3";
        viewModel.Msg[3] = "Original message 4";
        viewModel.Msg[4] = "Original message 5";

        BindingContext = viewModel;
    }
}

public class MainViewModel : ObservableObject
{
    private Messages _msg;
    public Messages Msg
    {
        get { return _msg ?? (_msg = new Messages()); }
        set { SetProperty(ref _msg, value); }
    }

    public ICommand UpdateMessage => new Command(() =>
           {
               Msg[2] = "New message 3";
               Msg[0] = "New message 1";
           });
}

这篇关于如何在 ViewModel 中使用数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆