如何在另一个 Page/Viewmodel 上使用在一个 ViewModel 中创建的数据?

How to use data created in one ViewModel on another Page/Viewmodel?

我目前正在为我正在开发的应用程序构建 UI,我在绑定方面遇到了一些问题。

场景:

我有一个枢轴控件,每个枢轴元素都包含一个额外的 Frame/Page。 现在我在第一个 PivotItem 上有一个 TextBlock。我将其绑定到 "string" 并使用按钮在按钮的两个可能内容之间切换。

当按钮在同一个 Page/Frame 上时,它就像一个魅力。但是当我在 MainPage 上实现一个按钮并为 MainPage 实现相同的 Viewmodel 时,它就不起作用了。它只会改变主页上的字符串内容。

是否可以对每个 Page/Frame 实施更改?

完成后,我有一个页面,我可以在其中使用串行端口收集数据。 我将数据保存到一个列表中,我希望能够从 2 个不同的 Pages/Frames 中使用这个列表。 考虑上面的场景,它可能会收集我有按钮获取数据的页面的数据,但它可能不会在其他页面上显示任何内容。 我怎样才能像我想要的那样构建它?

这是一个简短的例子:

Mainpage.xaml

<StackPanel>
    <Button Height="50" Width="200" Content="Change" FontSize="30" FontWeight="Bold" Margin="50 50 0 0" Click="{x:Bind MainViewModel.Change}"/>

    <Pivot x:Name="MainPivot" Margin="50 50">
        <PivotItem Header="Page 1">
            <Frame x:Name="Page1" />
        </PivotItem>
    </Pivot>
</StackPanel>

Mainpage.xaml.cs

public MainPage()
{
    this.InitializeComponent();
    Page1.Navigate(typeof(Page1));

    ViewModel = new MainViewModel();
}
public MainViewModel ViewModel { get; private set; }

Page1.xaml

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <TextBlock Text="{x:Bind Path=ViewModel.StringModel.String1, Mode=TwoWay}" FontSize="50" FontWeight="Bold" />

    <Button Content="Change" FontSize="30" FontWeight="Bold" Click="{x:Bind ViewModel.Change}"/>
</StackPanel> 

Page1.xaml.cs

public Page1()
{
    this.InitializeComponent();
    ViewModel = new MainViewModel();
}

public MainViewModel ViewModel { get; private set; }

MainViewModel.cs

private StringModel _stringModel = new StringModel();

public StringModel StringModel
{
    get => _stringModel;
    set
    {
        if (_stringModel != value)
        {
            _stringModel = value;
            OnPropertyChanged();
        }
    }
}

public void Change()
{
    if (StringModel.String1 == "Text1")
    {
        StringModel.String1 = "Text2";
    }
    else
    {
        StringModel.String1 = "Text1";
    }   
}

StringModel.cs

private string _string1 = "XXX";

    public string String1
    {
        get => _string1;
        set
        {
            _string1 = value;
            OnPropertyChanged();
        }
    }

通常 children 的 XAML parent 继承所述 parent 的绑定上下文。 所以不确定您是否需要将 VM 连接到您的框架。

但假设它不适用于 Frames,您正在为主页创建一个新的 MainViewModel 框架!

这里的解决方案是创建一个单例 MainViewModel 并获取它以连接 BindingContext

听起来您的应用程序缺少 "service layer" 或 "business layer"。您需要一个外部 class 来管理数据,并可以提供模型来填充您的 ViewModel:

我建议使用某种依赖注入,这样您的每个页面视图模型都会引用 DataProvider 服务 class。 class 串行端口工作以获取模型列表,并提供用于获取数据并将任何更新推送到 ViewModels 的接口。

处理共享的 事件 的好方法,比如可能出现在不同视图模型上的 "load data" 按钮是 Event Aggregator。可以注入 classes 的服务,可以在整个应用程序中引发或订阅事件。

您可以使用 Publisher-Subscriber 模式 (Pub-Sub)。

这里已经解释过了:Communication Between Views in MVVM (Pub-Sub Pattern)