一个 ViewModel 中的触发器 属性 从另一个 ViewModel (MessagingCenter) 更改
Trigger property changed in one ViewModel from another ViewModel (MessagingCenter)
我正在尝试将另一个 ViewModel 的更改通知一个 ViewModel。为此,我尝试使用 MessagingCenter。但是,由于某种原因,它似乎不起作用。有人可以放点灯吗,为什么我无法从一个视图中更改另一个视图中标签的颜色?
HomeViewModel.cs:
using System;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MessagingCenterApp.ViewModels
{
public class HomeViewModel : BaseViewModel
{
public HomeViewModel()
{
Title = "Home";
MessagingCenter.Subscribe<Object, Color>(this, "gaugeColor", (sender, arg) =>
{
this._gaugeColor = arg;
});
this.GaugeColor = Color.White;
}
private Color _gaugeColor;
public Color GaugeColor
{
get => _gaugeColor;
set
{
_gaugeColor = value;
OnPropertyChanged();
}
}
}
}
SettingsViewModel.cs:
using MessagingCenterApp.Models;
using MessagingCenterApp.Views;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MessagingCenterApp.ViewModels
{
public class SettingsViewModel : BaseViewModel
{
public SettingsViewModel()
{
Title = "Settings";
MessagingCenter.Send<Object, Color>(this, "gaugeColor", Color.FromHex(this.GaugeColor));
}
private string _gaugeColor;
public string GaugeColor
{
get => Preferences.Get("GaugeColor", "#17805d");
set
{
Preferences.Set("GaugeColor", value);
this.OnPropertyChanged();
}
}
}
}
编辑:
没有单独按钮的实现:
SettingsViewModel.cs:
using MessagingCenterApp.Models;
using MessagingCenterApp.Views;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MessagingCenterApp.ViewModels
{
public class SettingsViewModel : BaseViewModel
{
public ICommand changeCommand { get; set; }
public SettingsViewModel()
{
Title = "Settings";
GaugeColor = Color.Red;
changeCommand = new Command(changeColor);
}
private void changeColor()
{
GaugeColor = Color.FromHex(this.GaugeColorS);
MessagingCenter.Send<Object, Color>(this, "gaugeColor", GaugeColor);
}
private Color _gaugeColor;
public Color GaugeColor
{
get => _gaugeColor;
set
{
_gaugeColor = value;
this.OnPropertyChanged();
}
}
private string _gaugeColorS;
public string GaugeColorS
{
get => Preferences.Get("GaugeColor", "#17805d");
set
{
Preferences.Set("GaugeColor", value);
this.changeColor();
this.OnPropertyChanged();
}
}
}
}
HomeViewModel.cs:
using System;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MessagingCenterApp.ViewModels
{
public class HomeViewModel : BaseViewModel
{
public HomeViewModel()
{
Title = "Home";
MessagingCenter.Subscribe<Object, Color>(this, "gaugeColor", (sender, arg) =>
{
System.Diagnostics.Debug.WriteLine("received color = " + arg);
this.GaugeColor = arg;
});
this.GaugeColor = Color.Red;
}
private Color _gaugeColor;
public Color GaugeColor
{
get => _gaugeColor;
set
{
_gaugeColor = value;
OnPropertyChanged();
}
}
}
}
如果你想在当前页面属性重置时向另一个页面发送消息,你应该添加一个事件触发器(例如点击[=15=页面中的'Button' ]. 单击按钮后,向页面 HomePage
).
发送消息
我简化了你的代码,它在我这边工作正常。您可以修改它以满足您的需要。
BaseViewModel.cs
public class BaseViewModel : INotifyPropertyChanged
{
public IDataStore<Item> DataStore => DependencyService.Get<IDataStore<Item>>();
bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
public bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
HomeViewModel.cs
public class HomeViewModel : BaseViewModel
{
private Color _gaugeColor;
public Color GaugeColor
{
set { SetProperty(ref _gaugeColor, value); }
get { return _gaugeColor; }
}
public HomeViewModel()
{
Title = "Home";
MessagingCenter.Subscribe<Object, Color>(this, "gaugeColor", (sender, arg) =>
{
System.Diagnostics.Debug.WriteLine("received color = " + arg);
this.GaugeColor = arg;
});
this.GaugeColor = Color.Red;
}
}
SettingsViewModel.cs
public class SettingsViewModel : BaseViewModel
{
public ICommand changeCommand { get; set; }
public SettingsViewModel()
{
Title = "Settings";
GaugeColor = Color.Red;
changeCommand = new Command(changeColor);
}
private void changeColor(object obj)
{
GaugeColor = Color.Yellow;
MessagingCenter.Send<Object, Color>(this, "gaugeColor", GaugeColor);
}
Color _gaugeColor;
public Color GaugeColor
{
set { SetProperty(ref _gaugeColor, value); }
get { return _gaugeColor; }
}
}
SettingsPage.xaml(这里我加了Button)
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MessagingCenterApp.Views.SettingsPage"
Title="{Binding Title}"
xmlns:vm="clr-namespace:MessagingCenterApp.ViewModels"
Background="#121212"
x:Name="BrowseItemsPage">
<ContentPage.BindingContext>
<vm:SettingsViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Accent">#0d1117</Color>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Orientation="Vertical">
<Label Text="Gauge color:"></Label>
<Entry Text="{Binding GaugeColor}" Keyboard="Numeric"></Entry>
<Button Text="change color" Command="{Binding changeCommand}"/>
</StackLayout>
</ContentPage>
更新:
I mean when I type or select new colour on Settings page, I would like
to see new colour already
为此,您可以在SettingsViewModel
中添加MessagingCenter.Send
,如下所示:
Color _gaugeColor;
public Color GaugeColor
{
set {
SetProperty(ref _gaugeColor, value);
MessagingCenter.Send<Object, Color>(this, "gaugeColor", GaugeColor);
}
get { return _gaugeColor; }
}
如果您不想要按钮,可以删除 SettingsPage.xaml
中的 Button
。
我正在尝试将另一个 ViewModel 的更改通知一个 ViewModel。为此,我尝试使用 MessagingCenter。但是,由于某种原因,它似乎不起作用。有人可以放点灯吗,为什么我无法从一个视图中更改另一个视图中标签的颜色?
HomeViewModel.cs:
using System;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MessagingCenterApp.ViewModels
{
public class HomeViewModel : BaseViewModel
{
public HomeViewModel()
{
Title = "Home";
MessagingCenter.Subscribe<Object, Color>(this, "gaugeColor", (sender, arg) =>
{
this._gaugeColor = arg;
});
this.GaugeColor = Color.White;
}
private Color _gaugeColor;
public Color GaugeColor
{
get => _gaugeColor;
set
{
_gaugeColor = value;
OnPropertyChanged();
}
}
}
}
SettingsViewModel.cs:
using MessagingCenterApp.Models;
using MessagingCenterApp.Views;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MessagingCenterApp.ViewModels
{
public class SettingsViewModel : BaseViewModel
{
public SettingsViewModel()
{
Title = "Settings";
MessagingCenter.Send<Object, Color>(this, "gaugeColor", Color.FromHex(this.GaugeColor));
}
private string _gaugeColor;
public string GaugeColor
{
get => Preferences.Get("GaugeColor", "#17805d");
set
{
Preferences.Set("GaugeColor", value);
this.OnPropertyChanged();
}
}
}
}
编辑:
没有单独按钮的实现:
SettingsViewModel.cs:
using MessagingCenterApp.Models;
using MessagingCenterApp.Views;
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MessagingCenterApp.ViewModels
{
public class SettingsViewModel : BaseViewModel
{
public ICommand changeCommand { get; set; }
public SettingsViewModel()
{
Title = "Settings";
GaugeColor = Color.Red;
changeCommand = new Command(changeColor);
}
private void changeColor()
{
GaugeColor = Color.FromHex(this.GaugeColorS);
MessagingCenter.Send<Object, Color>(this, "gaugeColor", GaugeColor);
}
private Color _gaugeColor;
public Color GaugeColor
{
get => _gaugeColor;
set
{
_gaugeColor = value;
this.OnPropertyChanged();
}
}
private string _gaugeColorS;
public string GaugeColorS
{
get => Preferences.Get("GaugeColor", "#17805d");
set
{
Preferences.Set("GaugeColor", value);
this.changeColor();
this.OnPropertyChanged();
}
}
}
}
HomeViewModel.cs:
using System;
using System.Windows.Input;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace MessagingCenterApp.ViewModels
{
public class HomeViewModel : BaseViewModel
{
public HomeViewModel()
{
Title = "Home";
MessagingCenter.Subscribe<Object, Color>(this, "gaugeColor", (sender, arg) =>
{
System.Diagnostics.Debug.WriteLine("received color = " + arg);
this.GaugeColor = arg;
});
this.GaugeColor = Color.Red;
}
private Color _gaugeColor;
public Color GaugeColor
{
get => _gaugeColor;
set
{
_gaugeColor = value;
OnPropertyChanged();
}
}
}
}
如果你想在当前页面属性重置时向另一个页面发送消息,你应该添加一个事件触发器(例如点击[=15=页面中的'Button' ]. 单击按钮后,向页面 HomePage
).
我简化了你的代码,它在我这边工作正常。您可以修改它以满足您的需要。
BaseViewModel.cs
public class BaseViewModel : INotifyPropertyChanged
{
public IDataStore<Item> DataStore => DependencyService.Get<IDataStore<Item>>();
bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
public bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
HomeViewModel.cs
public class HomeViewModel : BaseViewModel
{
private Color _gaugeColor;
public Color GaugeColor
{
set { SetProperty(ref _gaugeColor, value); }
get { return _gaugeColor; }
}
public HomeViewModel()
{
Title = "Home";
MessagingCenter.Subscribe<Object, Color>(this, "gaugeColor", (sender, arg) =>
{
System.Diagnostics.Debug.WriteLine("received color = " + arg);
this.GaugeColor = arg;
});
this.GaugeColor = Color.Red;
}
}
SettingsViewModel.cs
public class SettingsViewModel : BaseViewModel
{
public ICommand changeCommand { get; set; }
public SettingsViewModel()
{
Title = "Settings";
GaugeColor = Color.Red;
changeCommand = new Command(changeColor);
}
private void changeColor(object obj)
{
GaugeColor = Color.Yellow;
MessagingCenter.Send<Object, Color>(this, "gaugeColor", GaugeColor);
}
Color _gaugeColor;
public Color GaugeColor
{
set { SetProperty(ref _gaugeColor, value); }
get { return _gaugeColor; }
}
}
SettingsPage.xaml(这里我加了Button)
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MessagingCenterApp.Views.SettingsPage"
Title="{Binding Title}"
xmlns:vm="clr-namespace:MessagingCenterApp.ViewModels"
Background="#121212"
x:Name="BrowseItemsPage">
<ContentPage.BindingContext>
<vm:SettingsViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Accent">#0d1117</Color>
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout Orientation="Vertical">
<Label Text="Gauge color:"></Label>
<Entry Text="{Binding GaugeColor}" Keyboard="Numeric"></Entry>
<Button Text="change color" Command="{Binding changeCommand}"/>
</StackLayout>
</ContentPage>
更新:
I mean when I type or select new colour on Settings page, I would like to see new colour already
为此,您可以在SettingsViewModel
中添加MessagingCenter.Send
,如下所示:
Color _gaugeColor;
public Color GaugeColor
{
set {
SetProperty(ref _gaugeColor, value);
MessagingCenter.Send<Object, Color>(this, "gaugeColor", GaugeColor);
}
get { return _gaugeColor; }
}
如果您不想要按钮,可以删除 SettingsPage.xaml
中的 Button
。