带有由模型 属性 填充的进度条的 ListView
ListView with a progress bar populated by Model property
亲爱的,
我想创建一个包含一些模型信息的列表视图,使用 INotifyPropertyChanged 来实时填充和更新我的信息。但是当我尝试在 Progress 函数中使用绑定时,它不起作用。
我的看法是:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
x:Class="H2XA.View.PatientView"
Title="Pacientes">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Label x:Name="Paciente1" Text="Paciente"
HorizontalOptions="Center"
VerticalOptions="Center"
/>
<ListView x:Name="Patients"
ItemSelected="OnSelection"
IsPullToRefreshEnabled="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Renomear" CommandParameter="{Binding .}"
Clicked="Renomear_Clicked" />
</ViewCell.ContextActions>
<StackLayout Padding="5,0,5,0">
<Label Text="{Binding Name}" Font="16"/>
<Label Text="{Binding Medidas}" Font="14" />
<ProgressBar ProgressColor="{Binding Bar_Color}"
Progress="{Binding CurrentProgress}"
PropertyChanged="ProgressBar_PropertyChanged"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
和
public partial class PatientView : ContentPage
{
public PatientView()
{
InitializeComponent();
BindingContext = App.PVM;
Patients.ItemsSource = App.PVM.AllPatient;
}
private async void OnSelection(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
await DisplayAlert("Selecionado", e.SelectedItem.ToString(), "Ok");
string a = e.SelectedItem.ToString().Substring(0, 12);
}
private void Renomear_Clicked(object sender, EventArgs e)
{
//replace name
var item = (MenuItem)sender;
(item.CommandParameter as Patient).Name = "new name";
}
private void ProgressBar_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
//This is the way that i found.
var item = (sender as ProgressBar) ;
if(item.Progress==0)
item.ProgressTo(1, 15000, Easing.Linear);
if (item.Progress == 1)
item.ProgressColor = Color.Green;
}
}
这是我找到的将 ProgressBars 列表填充到对象中的方法。但它不喜欢实现解决方案的好方法,因为我无法控制 ProgressBar 和 Easing 的时间 "Linear" 它不是真正线性的大数字。
ProgressTo的第一个参数是Progress,我想在第二个参数一起设置的时候显示。
我想在我的模型中实现作为对象的参数。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using H2XA.ViewModel;
using Xamarin.Forms;
namespace H2XA.Model
{
public class Patient:INotifyPropertyChanged
{
public Guid Id { get; set; }
public DateTime examdate;
public int cronometro;
public decimal barCronometro;
public Color Bar_Color;
private string name;
private string medidas;
public Patient()
{
cronometro = 0;
Device.StartTimer(TimeSpan.FromSeconds(15), () =>
{
if (cronometro < 6)
{
Bar_Color = Color.Blue;
cronometro++;
}
else
{
if (cronometro == 60)
{
Bar_Color = Color.Red;
}
}
CurrentProgress = (cronometro / 60);
return true;
});
}
private decimal _currentProgress;
public decimal CurrentProgress
{
get { return _currentProgress; }
private set
{
_currentProgress = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged();//Esse comando faz a tela ser atualizada quando algo é inserido.
}
}
public string Medidas
{
get { return medidas; }
set
{
medidas = value;
OnPropertyChanged();//Esse comando faz a tela ser atualizada quando algo é inserido.
}
}
}
}
但是当我这样做时,没有动画,也没有更新图中的时间,只有当条件工作完成并且我的栏显示已满时才更新时间。我不知道我的绑定是否有效,对我来说我做了一些有意义的事情。
我正在检查代码并注意到我的 ProgressBar_PropertyChanged 每次都会被调用,这对我的应用程序效率也不利。谁能帮助我改进我的代码并组织我的功能以更好地组织我的 MVVM 项目。
提前致谢
吉列尔梅·马克斯
- 当 ProgressBar 不在 ListView 中时。
你应该Overriding the Binding Mode,目标属性上的默认绑定模式是
OneWay
。当你的模型数据改变时,progressbar的进度已经设置好了there.It 不会触发 ProgressTo
. 这个方法
这里你应该使用绑定模式TwoWay
,它会正确显示。
示例代码如下:
Xaml:
<ProgressBar x:Name="progressBar"
Progress="{Binding CurrentProgress,Mode=TwoWay}"
PropertyChanged="ProgressBar_PropertyChanged"/>
ContentPage:当模型数据改变时,它会起作用。
private void ProgressBar_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
//This is the way that i found.
var item = (sender as ProgressBar);
//if (item.Progress == 0)
item.ProgressTo(1, 15000, Easing.Linear);
//if (item.Progress == 1)
//item.ProgressColor = Color.Green;
}
你可以删除ProgressBar_PropertyChanged
方法。当数据改变时,按如下操作:
dataModel.CurrentProgress = 0.8;
...
progressBar.ProgressTo(dataModel.CurrentProgress, 3000, Easing.Linear);
- 当ProgressBar绑定在ListView和MVVM时,它不会发生
Animation
.这里有一个article供参考
解法:
这里是使用Timer
定时任务改变进度数据的方法。
Timer timer; // create a timer
DataModel dataModel; // data model
private double ApiProgressData = 0; // Simulate data from Api
Init Timer 及其事件处理程序:
timer = new Timer();
timer.Interval = 100;
timer.Elapsed += Timer_Elapsed;
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (ApiProgressData > dataModel.CurrentProgress)
{
dataModel.CurrentProgress = dataModel.CurrentProgress + 0.01;
if ((ApiProgressData - dataModel.CurrentProgress) < 0.00001)
{
Device.BeginInvokeOnMainThread(() =>
{
timer.Stop();
});
}
}
else if (ApiProgressData < dataModel.CurrentProgress)
{
dataModel.CurrentProgress = dataModel.CurrentProgress - 0.01;
if (( dataModel.CurrentProgress - ApiProgressData ) < 0.00001)
{
Device.BeginInvokeOnMainThread(() =>
{
timer.Stop();
});
}
}else{
Device.BeginInvokeOnMainThread(() =>
{
timer.Stop();
});
}
}
Api数据改变后,使用Timer改变模型的数据:
ApiProgressData = 0.8; // Simulate data is 0.8 to test
timer.Start();
或者你可以试试上面文章中提到的第三方库。
亲爱的,
我想创建一个包含一些模型信息的列表视图,使用 INotifyPropertyChanged 来实时填充和更新我的信息。但是当我尝试在 Progress 函数中使用绑定时,它不起作用。
我的看法是:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
x:Class="H2XA.View.PatientView"
Title="Pacientes">
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Label x:Name="Paciente1" Text="Paciente"
HorizontalOptions="Center"
VerticalOptions="Center"
/>
<ListView x:Name="Patients"
ItemSelected="OnSelection"
IsPullToRefreshEnabled="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Text="Renomear" CommandParameter="{Binding .}"
Clicked="Renomear_Clicked" />
</ViewCell.ContextActions>
<StackLayout Padding="5,0,5,0">
<Label Text="{Binding Name}" Font="16"/>
<Label Text="{Binding Medidas}" Font="14" />
<ProgressBar ProgressColor="{Binding Bar_Color}"
Progress="{Binding CurrentProgress}"
PropertyChanged="ProgressBar_PropertyChanged"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
和
public partial class PatientView : ContentPage
{
public PatientView()
{
InitializeComponent();
BindingContext = App.PVM;
Patients.ItemsSource = App.PVM.AllPatient;
}
private async void OnSelection(object sender, SelectedItemChangedEventArgs e)
{
if (e.SelectedItem == null)
{
return;
}
await DisplayAlert("Selecionado", e.SelectedItem.ToString(), "Ok");
string a = e.SelectedItem.ToString().Substring(0, 12);
}
private void Renomear_Clicked(object sender, EventArgs e)
{
//replace name
var item = (MenuItem)sender;
(item.CommandParameter as Patient).Name = "new name";
}
private void ProgressBar_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
//This is the way that i found.
var item = (sender as ProgressBar) ;
if(item.Progress==0)
item.ProgressTo(1, 15000, Easing.Linear);
if (item.Progress == 1)
item.ProgressColor = Color.Green;
}
}
这是我找到的将 ProgressBars 列表填充到对象中的方法。但它不喜欢实现解决方案的好方法,因为我无法控制 ProgressBar 和 Easing 的时间 "Linear" 它不是真正线性的大数字。
ProgressTo的第一个参数是Progress,我想在第二个参数一起设置的时候显示。
我想在我的模型中实现作为对象的参数。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using H2XA.ViewModel;
using Xamarin.Forms;
namespace H2XA.Model
{
public class Patient:INotifyPropertyChanged
{
public Guid Id { get; set; }
public DateTime examdate;
public int cronometro;
public decimal barCronometro;
public Color Bar_Color;
private string name;
private string medidas;
public Patient()
{
cronometro = 0;
Device.StartTimer(TimeSpan.FromSeconds(15), () =>
{
if (cronometro < 6)
{
Bar_Color = Color.Blue;
cronometro++;
}
else
{
if (cronometro == 60)
{
Bar_Color = Color.Red;
}
}
CurrentProgress = (cronometro / 60);
return true;
});
}
private decimal _currentProgress;
public decimal CurrentProgress
{
get { return _currentProgress; }
private set
{
_currentProgress = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string Name
{
get { return name; }
set
{
name = value;
OnPropertyChanged();//Esse comando faz a tela ser atualizada quando algo é inserido.
}
}
public string Medidas
{
get { return medidas; }
set
{
medidas = value;
OnPropertyChanged();//Esse comando faz a tela ser atualizada quando algo é inserido.
}
}
}
}
但是当我这样做时,没有动画,也没有更新图中的时间,只有当条件工作完成并且我的栏显示已满时才更新时间。我不知道我的绑定是否有效,对我来说我做了一些有意义的事情。
我正在检查代码并注意到我的 ProgressBar_PropertyChanged 每次都会被调用,这对我的应用程序效率也不利。谁能帮助我改进我的代码并组织我的功能以更好地组织我的 MVVM 项目。
提前致谢
吉列尔梅·马克斯
- 当 ProgressBar 不在 ListView 中时。
你应该Overriding the Binding Mode,目标属性上的默认绑定模式是
OneWay
。当你的模型数据改变时,progressbar的进度已经设置好了there.It 不会触发ProgressTo
. 这个方法
这里你应该使用绑定模式TwoWay
,它会正确显示。
示例代码如下:
Xaml:
<ProgressBar x:Name="progressBar"
Progress="{Binding CurrentProgress,Mode=TwoWay}"
PropertyChanged="ProgressBar_PropertyChanged"/>
ContentPage:当模型数据改变时,它会起作用。
private void ProgressBar_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
//This is the way that i found.
var item = (sender as ProgressBar);
//if (item.Progress == 0)
item.ProgressTo(1, 15000, Easing.Linear);
//if (item.Progress == 1)
//item.ProgressColor = Color.Green;
}
你可以删除ProgressBar_PropertyChanged
方法。当数据改变时,按如下操作:
dataModel.CurrentProgress = 0.8;
...
progressBar.ProgressTo(dataModel.CurrentProgress, 3000, Easing.Linear);
- 当ProgressBar绑定在ListView和MVVM时,它不会发生
Animation
.这里有一个article供参考
解法:
这里是使用Timer
定时任务改变进度数据的方法。
Timer timer; // create a timer
DataModel dataModel; // data model
private double ApiProgressData = 0; // Simulate data from Api
Init Timer 及其事件处理程序:
timer = new Timer();
timer.Interval = 100;
timer.Elapsed += Timer_Elapsed;
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (ApiProgressData > dataModel.CurrentProgress)
{
dataModel.CurrentProgress = dataModel.CurrentProgress + 0.01;
if ((ApiProgressData - dataModel.CurrentProgress) < 0.00001)
{
Device.BeginInvokeOnMainThread(() =>
{
timer.Stop();
});
}
}
else if (ApiProgressData < dataModel.CurrentProgress)
{
dataModel.CurrentProgress = dataModel.CurrentProgress - 0.01;
if (( dataModel.CurrentProgress - ApiProgressData ) < 0.00001)
{
Device.BeginInvokeOnMainThread(() =>
{
timer.Stop();
});
}
}else{
Device.BeginInvokeOnMainThread(() =>
{
timer.Stop();
});
}
}
Api数据改变后,使用Timer改变模型的数据:
ApiProgressData = 0.8; // Simulate data is 0.8 to test
timer.Start();
或者你可以试试上面文章中提到的第三方库。