简体   繁体   English

如何将属性作为参数传递给 Converter 并且属性不在列表 itemsource 上下文 xaml - Xamarin

[英]How can I pass a property as a param to Converter and property is outside of list itemsource context xaml - Xamarin

I am working on Listview , one of Label inside Cell using Converter , I need to pass one property as converter parameter which is not part of itemsource but defined in viewmodel .我正在使用ConverterCell内的Label中的一个Listview上工作,我需要将一个属性作为converter parameter传递,该属性不是itemsource的一部分,而是在viewmodel中定义。

This is my code这是我的代码

<Label FontSize="10"    
Text="Insufficient Funds"                                              
IsVisible="{Binding balance, Converter={StaticResource IsInsufficientBalanceConverter}, Source={x:Reference Name=multiCardPage}, ConverterParameter={x:Reference BindingContext.Subtotal} }">

Getting this exception得到这个异常

Xamarin.Forms.Xaml.XamlParseException: 'Position 120:52. Can not find the object referenced by BindingContext.Subtotal'

What I want to do:我想做的事:
I have a value Subtotal (not part of itemsource).我有一个值Subtotal (不是 itemsource 的一部分)。 In itemsource, there is balance property, if balance is less than Subtotal , I want to display above Insufficient Funds Label otherwise this Label should be invisible.在 itemsource 中,有balance属性,如果balance小于Subtotal ,我想显示在Insufficient Funds Label ,否则这个Label应该是不可见的。 For this I want to pass Subtotal to Converter with balance so that I can get true or false value.为此,我想将小计传递给带有余额的转换器,以便获得true值或false值。

How can I make it work?我怎样才能让它工作?

Edit 1: I want view and converter to listen the changes in subtotal value and update the UI accordingly so that Insufficient balance label can visible/invisible as per balance in listview .编辑 1:我希望viewconverter监听subtotal值的变化并相应地更新 UI,以便Insufficient balance label可以根据listview中的余额可见/不可见。 I have tried multibindings but that is not supporting the case with list/collection.我已经尝试过多重绑定,但这不支持列表/集合的情况。 How can I fix this.我怎样才能解决这个问题。

How can I pass a property as a param to Converter and property is outside of list itemsource context xaml - Xamarin如何将属性作为参数传递给 Converter 并且属性不在列表 itemsource 上下文 xaml - Xamarin

You don't need to pass the Subtotal as a param to Converter, you can just refer the Subtotal in your Converter class.您不需要将Subtotal作为参数传递给转换器,您只需在转换器 class 中引用Subtotal即可。

Please refer to the following code(suppose the type of Subtotal is int ):请参考以下代码(假设Subtotal的类型为int ):

public class InsufficientBalanceConverter : IValueConverter
{
    const int Subtotal = 5;
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
         int mValue =  (int)value;

        if (mValue < Subtotal)
        {

            return true;
        }
        else {
            return false;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

In the xaml, we can do like this:在 xaml 中,我们可以这样做:

<Label x:Name="mQuantity" Text="Insufficient Funds"    
       IsVisible="{Binding balance, Converter={StaticResource MyInsufficientBalanceConverter} }" />

And the Resources in xaml is: xaml 中的Resources是:

<ContentPage.Resources>
    <ResourceDictionary>
        <converts:InsufficientBalanceConverter x:Key="MyInsufficientBalanceConverter"></converts:InsufficientBalanceConverter>
    </ResourceDictionary>
</ContentPage.Resources>

You can escape the DataContext of the individual item in the ItemSource by targetting the parent ItemsControl's DataContext with RelativeSource:您可以通过使用 RelativeSource 定位父 ItemsControl 的 DataContext 来转义 ItemSource 中单个项目的 DataContext:

<TextBlock Text="{Binding DataContext.SubTotal, 
      RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />

You could also go all of the way up to the Window or UserControl that the viewmodel backs:您也可以 go 一直到视图模型支持的 Window 或 UserControl:

<TextBlock Text="{Binding DataContext.SubTotal, 
      RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>

<TextBlock Text="{Binding DataContext.SubTotal, 
      RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />

Alternatively, you can add an x:Name="abcd" to a specific element, like a UserControl or Window (whatever is top-level for the viewmodel) and target the other DataContext by name instead:或者,您可以将x:Name="abcd"添加到特定元素,例如 UserControl 或 Window (无论是视图模型的顶级),并按名称定位其他 DataContext :

<Window x:Name="abcd">
....

<TextBlock Text="{Binding DataContext.SubTotal, ElementName=abcd}" />

This is an addition to Jessie's answer .这是对Jessie 的回答的补充。

You can use MessagingCenter to tell the page the new subtotal.您可以使用 MessagingCenter 告诉页面新的小计。

In this example, properties are bound to the page.在此示例中,属性绑定到页面。 If using MVVM, some of the code will instead be in the VM.如果使用 MVVM,一些代码将改为在 VM 中。

PaymentPage.xaml: PaymentPage.xaml:

<Label Text="{Binding Subtotal}" />

PaymentPage.xaml.cs: PaymentPage.xaml.cs:

public partial class PaymentPage : ContentPage
{
    public PaymentPage()
    {
        InitializeComponent();
        BindingContext = this;
    }

    public int Subtotal
    {
        get => _subtotal;
        set
        {
            _subtotal = value;
            OnPropertyChanged();
        }
    }
    private int _subtotal;


    protected override void OnAppearing()
    {
        base.OnAppearing();

        MessagingCenter.Subscribe<PaymentCalc, int>(this, "NewSubTotal", (sender, value) =>
        {
            Subtotal = value;
        });
    }

    protected override void OnDisappearing()
    {
        base.OnDisappearing();

        MessagingCenter.Unsubscribe<PaymentCalc, int>(this, "NewSubTotal");
    }
}

In order to use MessagingCenter, there needs to be some class that will send the message.为了使用 MessagingCenter,需要有一些 class 来发送消息。 Here, I define PaymentCalc .在这里,我定义PaymentCalc

PaymentCalc.cs: PaymentCalc.cs:

class PaymentCalc
{
    public void NewSubTotal(int value)
    {
        MessagingCenter.Send(this, "NewSubTotal", value);
    }
}

Now anywhere in code, do this, to calculate a new Subtotal, and send it to PaymentPage:现在在代码中的任何地方,执行此操作,以计算新的小计,并将其发送到 PaymentPage:

var it = new PaymentCalc();
it.NewSubTotal(12345);

If you already have a class in which you are doing this calculation, then simply add NewSubTotal to it, or put that Send message in some appropriate method.如果您已经有一个 class 正在执行此计算,则只需将 NewSubTotal 添加到其中,或将该发送消息放入某种适当的方法中。 You'll need to change PaymentPage's Subscribe and Unsubscribe to use the name of your class, instead of PaymentCalc.您需要更改 PaymentPage 的订阅和取消订阅以使用 class 的名称,而不是 PaymentCalc。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM