【问题标题】:Xamarin ProgressBar bindingXamarin ProgressBar 绑定
【发布时间】:2019-09-16 12:41:42
【问题描述】:

我有一个包含卡片视图的页面。

BadgeView.cs 的 C# 代码(BadgeView XAML 具有名为 card 的 stacklayout):

 public BadgeView(BadgesGroup badgesGroup)
        {
            InitializeComponent();
            BadgeLogo.Source = badgesGroup.Logo;
            var cardsview = new CardsView
            {
                IsClippedToBounds = true,
                IsCyclical = true,
                MoveWidthPercentage = 0.3,
                WidthRequest = 250,
                HeightRequest=250,
                ItemsSource = badgesGroup.Badges,
                ItemTemplate = new DataTemplate(() => new BadgePopUp())
            };
            cardsview.Children.Add(new IndicatorsControl());
            cardsview.Children.Add(new RightArrowControl());
            cardsview.Children.Add(new LeftArrowControl());
            card.Children.Add(cardsview);
        }

卡片视图项目源设置为具有此模型的徽章对象列表:

public class badge {
string Name {get;set;}
string Description {get;set;}
int CurrentProgress {get;set;}
int GoalProgress {get;set;}
}

itemtemplate BadgePopUp 是:

<StackLayout 
    Orientation="Vertical"
    HorizontalOptions="Center"
    VerticalOptions="Start"
    Padding="5"
    BackgroundColor="Goldenrod">
    <StackLayout.Resources>
        <ResourceDictionary>
            <local:ProgressConverter x:Key="xprogress" xCurrentProgress="{Binding CurrentProgress}"
                                     xGoalProgress="{Binding  GoalProgress}"/>
        </ResourceDictionary>
    </StackLayout.Resources>
    <StackLayout Orientation="Vertical">
        <Label Text="{Binding Title}"></Label>
        <Label Text="{Binding Description}"></Label>
    </StackLayout>
    <StackLayout Orientation="Horizontal">
        <Label Text="{Binding Name}"></Label>
        <ProgressBar x:Name="Progressbar" ProgressColor="Purple" 
            Progress="{Binding Converter={StaticResource xprogress}}">
        </ProgressBar>
        <Label Text="{Binding Description}"></Label>
    </StackLayout>
</StackLayout>

在 cardview 里面有两个标签,分别绑定了 Name 和 description 。 还有一个progressBar。

我想要做的是把 currentProgress 除以 GoalProgress 并将结果设置为 progressbar.progress 。

我尝试使用转换器,但它对我不起作用。 这是转换器的代码

public class ProgressConverter : IValueConverter
    {
        public int xCurrentProgress { get; set; }
        public int xGoalProgress { get;set; }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {

            return (float) xCurrentProgress / xGoalProgress;
        }

这对我有用:

 <local:ProgressConverter x:Key="xprogress" xCurrentProgress="2"
                                         xGoalProgress="3"/>

但是这行不通

 <local:ProgressConverter x:Key="xprogress" xCurrentProgress="{Binding CurrentProgress}"
                                         xGoalProgress="{Binding  GoalProgress}"/>

出现以下错误:

No property, bindable property, or event found for 'xCurrentProgress', or mismatching type between value and property.

有什么建议吗?

【问题讨论】:

  • 提供完整的代码或示例,以便人们更好地帮助您。
  • @LucasZhang-MSFT 谢谢,刚刚编辑并添加了示例代码。

标签: xaml xamarin mvvm progress-bar


【解决方案1】:

也许你误解了IValueConverterViewModel 的使用。如果要绑定数据,需要创建 ViewModel 进行绑定。而如果要转换值,首先需要绑定一个数据源,然后绑定一个值转换器来转换数据源的参数。看看这个Xamarin.Forms Binding Value Converters文档。

数据绑定通常将数据从源属性传输到目标属性,在某些情况下从目标属性传输到源属性。

从代码中您只需绑定一个 IValueConverter ,这将不起作用。

这是一个关于使用 ViewModel示例

public class ProgresssModel : INotifyPropertyChanged
{
    private int currentprogressvalue;

    public int CurrentProgressValue
    {
        set
        {
            if (currentprogressvalue != value)
            {
                currentprogressvalue = value;
                OnPropertyChanged("ProgressValue");
                progressvalue = (double)currentprogressvalue / totalprogressvalue;
            }
        }
        get
        {
            return currentprogressvalue;
        }
    }

    private int totalprogressvalue;

    public int TotalProgressValue
    {
        set
        {
            if (totalprogressvalue != value)
            {
                totalprogressvalue = value;
                OnPropertyChanged("ProgressValue");
                progressvalue = (double)currentprogressvalue / totalprogressvalue;
            }
        }
        get
        {
            return totalprogressvalue;
        }
    }

    private double progressvalue;

    public double ProgressValue
    {
        set
        {
            if (progressvalue != value)
            {
                progressvalue = value;
                OnPropertyChanged("ProgressValue");
            }
        }
        get
        {
            return progressvalue;
        }
    }

    public ProgresssModel()
    {
        currentprogressvalue = 30;
        totalprogressvalue = 100;
        progressvalue = (double)currentprogressvalue / totalprogressvalue;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

XAML 中,添加一个非自定义的ProgressBar,并添加Button 以显示更改的数据 例如运行时:

<StackLayout BackgroundColor="WhiteSmoke" Padding="20">
    <Label Text="Welcome to Xamarin.Forms!"
        VerticalOptions="CenterAndExpand" 
        HorizontalOptions="CenterAndExpand" />
    <ProgressBar x:Name="myprogress" Progress="{Binding ProgressValue}"/>
    <Button Text="change" Clicked="Button_Clicked"/>
</StackLayout>

现在可以将其绑定到 ContentPage 中的ProgressBar

public partial class SecondPage : ContentPage
{

    ProgresssModel progresssModel;
    public SecondPage()
    {
        InitializeComponent();

        progresssModel = new ProgresssModel();
        myprogress.BindingContext = progresssModel;
    }

    private void Button_Clicked(object sender, EventArgs e)
    {
        progresssModel.CurrentProgressValue = 40;
        progresssModel.TotalProgressValue = 100;
    }
}

效果

【讨论】:

  • 会试一试.. 但是在 ProgressModel 和按钮中,两者的值都设置为 30 、 40 和 100 ...我怎样才能从它们的父元素(cardView)ItemSource 中获取它们的值
  • @user2596181 您可以将ProgressModel 设置为静态实例。由cardView 的ItemSource 等其他元素更新。
  • 我知道如何从 xaml 访问 itemSource 数据,如下所示: 描述是徽章对象中的字符串。但我不知道如何从 C# 中的代码访问它,你能举个例子吗?
  • @user2596181 好的,例如:label.SetBinding(Label.TextProperty, new ProgresssModel().TextValue);
  • 这个例子设置一个绑定到 label 。我的意思是我已经有一个带有 itemsource 和 itemTemplate 的 cardView,itemtemplate 有进度条,进度条从 cardview itemsource 中获取两个值并将它们分开。我可以像这样为进度条设置一个值: 但我不知道如何划分 CurrentProgress 和 GoalProgress 并将进度条进度设置为结果。我希望我说得更清楚。
猜你喜欢
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-09
  • 2014-10-30
  • 2021-04-05
  • 1970-01-01
相关资源
最近更新 更多