尝试使用视图模型中的命令通过数据绑定更新图像按钮中的图像源 - 不起作用
Trying to update an image source in an imagebutton with data binding using a command in the viewmodel - not working
请原谅新手问题,但我正在努力理解我哪里出错了...
我正在尝试通过绑定 xaml 中的图像源来更改图像按钮(在网格中):
<ImageButton x:Name="playButton"
Source="{Binding PlayImage}"
Command="{Binding PlayCommand}"
Grid.Row="1"
Grid.Column="0"
BorderColor="#fafafa"
BackgroundColor="#fafafa"
/>
ImageButton 最初加载正确的'play.png'。
命令 'PlayCommand' 正在处理绑定。这应该更改 PlayImage 的值以在用户单击图像按钮时显示 'pause.png' 图像。尽管 PlayImage 变量的值发生了变化,但图像不会更新。请有人能告诉我我错过了什么吗?这是我的视图模型:
public class SermonDetailViewModel : BaseViewModel
{
public Sermon Sermon { get; set; }
public ICommand PlayCommand { private set; get; }
private ImageSource _playImage;
public ImageSource PlayImage
{
get { return _playImage; }
set
{
_playImage = value;
SetProperty(ref _playImage, value);
}
}
public SermonDetailViewModel(Sermon sermon = null)
{
if (sermon != null)
{
Title = sermon.STitle;
MP3Filepath = sermon.SLink;
PlayCommand = new Command(async () => await StartPlayer());
_playImage = "play.png";
}
Sermon = sermon;
}
async Task StartPlayer()
{
await CrossMediaManager.Current.Play(MP3Filepath);
_playImage = "pause.png";
Console.WriteLine(_playImage);
Console.WriteLine(PlayImage);
}
这是我的 baseViewModel 代码,它使用 class INotifyPropertyChanged 并设置 setProperty 方法:
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); }
}
string mp3filepath = string.Empty;
public string MP3Filepath
{
get { return mp3filepath; }
set { SetProperty(ref mp3filepath, value); }
}
protected 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;
}
非常感谢您的帮助.....谢谢!
尝试
Source="{Binding PlayImage, Mode=TwoWay }"
这也可以帮助您进行绑定
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/binding-mode
您正在设置私有支持字段,而不是 public 属性。这意味着 PropertyChanged
事件不会被引发
async Task StartPlayer()
{
await CrossMediaManager.Current.Play(MP3Filepath);
// should be PlayImage = "pause.png";
_playImage = "pause.png";
Console.WriteLine(_playImage);
Console.WriteLine(PlayImage);
}
我尝试了你的代码,做了一个样本来测试,我同意Jason的意见,请尝试设置PlayImage值,不要设置_playImage,我发现虽然PlayImage的值已经更新,但它是未绑定到 ImageButton。
请像下面的代码一样更改代码:
public SermonDetailViewModel(Sermon sermon = null)
{
if (sermon != null)
{
Title = sermon.STitle;
MP3Filepath = sermon.SLink;
PlayCommand = new Command(async () => await StartPlayer());
PlayImage= "play.png";
}
Sermon = sermon;
}
async Task StartPlayer()
{
await CrossMediaManager.Current.Play(MP3Filepath);
PlayImage= "pause.png";
Console.WriteLine(_playImage);
Console.WriteLine(PlayImage);
}
我也做了一个样例,你可以看看:
<ImageButton
BackgroundColor="#fafafa"
BorderColor="#fafafa"
Command="{Binding PlayCommand}"
HeightRequest="50"
Source="{Binding PlayImage}"
WidthRequest="50" />
public partial class Page4 : ContentPage
{
public Page4()
{
InitializeComponent();
this.BindingContext = new SermonDetailViewModel();
}
}
public class SermonDetailViewModel:ViewModelBase
{
public ICommand PlayCommand { private set; get; }
private ImageSource _playImage;
public ImageSource PlayImage
{
get { return _playImage; }
set
{
_playImage = value;
RaisePropertyChanged("PlayImage");
}
}
public SermonDetailViewModel()
{
PlayCommand = new Command(method1);
_playImage = "check.png";
}
private void method1()
{
PlayImage = "plu3.png";
}
}
它适用于代码:
private ImageSource _playImage;
public ImageSource PlayImage
{
get { return _playImage; }
set
{
_playImage = value;
Notify("PlayImage");
}
}
protected void Notify(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
请原谅新手问题,但我正在努力理解我哪里出错了...
我正在尝试通过绑定 xaml 中的图像源来更改图像按钮(在网格中):
<ImageButton x:Name="playButton"
Source="{Binding PlayImage}"
Command="{Binding PlayCommand}"
Grid.Row="1"
Grid.Column="0"
BorderColor="#fafafa"
BackgroundColor="#fafafa"
/>
ImageButton 最初加载正确的'play.png'。
命令 'PlayCommand' 正在处理绑定。这应该更改 PlayImage 的值以在用户单击图像按钮时显示 'pause.png' 图像。尽管 PlayImage 变量的值发生了变化,但图像不会更新。请有人能告诉我我错过了什么吗?这是我的视图模型:
public class SermonDetailViewModel : BaseViewModel
{
public Sermon Sermon { get; set; }
public ICommand PlayCommand { private set; get; }
private ImageSource _playImage;
public ImageSource PlayImage
{
get { return _playImage; }
set
{
_playImage = value;
SetProperty(ref _playImage, value);
}
}
public SermonDetailViewModel(Sermon sermon = null)
{
if (sermon != null)
{
Title = sermon.STitle;
MP3Filepath = sermon.SLink;
PlayCommand = new Command(async () => await StartPlayer());
_playImage = "play.png";
}
Sermon = sermon;
}
async Task StartPlayer()
{
await CrossMediaManager.Current.Play(MP3Filepath);
_playImage = "pause.png";
Console.WriteLine(_playImage);
Console.WriteLine(PlayImage);
}
这是我的 baseViewModel 代码,它使用 class INotifyPropertyChanged 并设置 setProperty 方法:
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); }
}
string mp3filepath = string.Empty;
public string MP3Filepath
{
get { return mp3filepath; }
set { SetProperty(ref mp3filepath, value); }
}
protected 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;
}
非常感谢您的帮助.....谢谢!
尝试
Source="{Binding PlayImage, Mode=TwoWay }"
这也可以帮助您进行绑定 https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/data-binding/binding-mode
您正在设置私有支持字段,而不是 public 属性。这意味着 PropertyChanged
事件不会被引发
async Task StartPlayer()
{
await CrossMediaManager.Current.Play(MP3Filepath);
// should be PlayImage = "pause.png";
_playImage = "pause.png";
Console.WriteLine(_playImage);
Console.WriteLine(PlayImage);
}
我尝试了你的代码,做了一个样本来测试,我同意Jason的意见,请尝试设置PlayImage值,不要设置_playImage,我发现虽然PlayImage的值已经更新,但它是未绑定到 ImageButton。
请像下面的代码一样更改代码:
public SermonDetailViewModel(Sermon sermon = null)
{
if (sermon != null)
{
Title = sermon.STitle;
MP3Filepath = sermon.SLink;
PlayCommand = new Command(async () => await StartPlayer());
PlayImage= "play.png";
}
Sermon = sermon;
}
async Task StartPlayer()
{
await CrossMediaManager.Current.Play(MP3Filepath);
PlayImage= "pause.png";
Console.WriteLine(_playImage);
Console.WriteLine(PlayImage);
}
我也做了一个样例,你可以看看:
<ImageButton
BackgroundColor="#fafafa"
BorderColor="#fafafa"
Command="{Binding PlayCommand}"
HeightRequest="50"
Source="{Binding PlayImage}"
WidthRequest="50" />
public partial class Page4 : ContentPage
{
public Page4()
{
InitializeComponent();
this.BindingContext = new SermonDetailViewModel();
}
}
public class SermonDetailViewModel:ViewModelBase
{
public ICommand PlayCommand { private set; get; }
private ImageSource _playImage;
public ImageSource PlayImage
{
get { return _playImage; }
set
{
_playImage = value;
RaisePropertyChanged("PlayImage");
}
}
public SermonDetailViewModel()
{
PlayCommand = new Command(method1);
_playImage = "check.png";
}
private void method1()
{
PlayImage = "plu3.png";
}
}
它适用于代码:
private ImageSource _playImage;
public ImageSource PlayImage
{
get { return _playImage; }
set
{
_playImage = value;
Notify("PlayImage");
}
}
protected void Notify(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}