简体   繁体   English

Xamarin 滑块:“值是最大值的无效值”(仅当导航离开页面时)

[英]Xamarin Slider: 'Value is an invalid value for Maximum' (Only when navigating away from a page)

I have a need to display different UI elements per item in a CollectionView .我需要在CollectionView中为每个项目显示不同的 UI 元素。 The base type of each item in the CollectionView is a Setting . CollectionView中每个项目的基本类型是一个Setting There are different types of settings: AnalogSetting , BooleanSetting , RangeSetting , etc. Each derived class has a different set of UI elements to allow the user to interact with it.有不同类型的设置: AnalogSettingBooleanSettingRangeSetting等。每个派生类都有一组不同的 UI 元素以允许用户与其交互。 BooleanSetting may have a simple toggle switch while the AnalogSetting has a slider. BooleanSetting可能有一个简单的切换开关,而AnalogSetting有一个滑块。 The amount and types of settings are delivered at runtime and can change on the fly.设置的数量和类型在运行时提供,并且可以即时更改。

The simplest way I could manage this was to use a DataTemplateSelector and then define different DataTemplates for each derived Setting class.我可以管理的最简单的方法是使用DataTemplateSelector ,然后为每个派生的Setting类定义不同的DataTemplates There is a particular DataTemplate that causes my app to crash whenever I navigate away from the page that is displaying the CollectionView .当我离开显示CollectionView的页面时,有一个特定的DataTemplate会导致我的应用程序崩溃。

I have the following CollectionView :我有以下CollectionView

...
<CollectionView 
    x:Name="SettingListView"
    ItemsSource="{Binding Settings}"
    ItemTemplate="{StaticResource settingSelector}"
    SelectionMode="None">
        </CollectionView>

The particular DataTemplate that is causing me grief:引起我悲伤的特定DataTemplate

<DataTemplate x:Key="AnalogSetting">
    <StackLayout x:DataType="model:AnalogSetting">
        <Label Text="{Binding Name}"/>
        <Slider Maximum="{Binding MaximumValue}" Minimum="{Binding MinimumValue}" Value="{Binding AnalogValue}">
            <Slider.Behaviors>
                <behaviors:SliderBehavior Command="{Binding SetValue}" />
            </Slider.Behaviors>
        </Slider>
    </StackLayout>
</DataTemplate>

The SliderBehavior class being used in the DataTemplate :DataTemplate中使用的SliderBehavior类:

public class SliderBehavior : Behavior<Slider>
{
    public static readonly BindableProperty CommandProperty = BindableProperty.Create(nameof(Command), typeof(ICommand), typeof(SliderBehavior), null);

    public Slider Bindable { get; private set; }

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    protected override void OnAttachedTo(Slider bindable)
    {
        base.OnAttachedTo(bindable);
        Bindable = bindable;
        Bindable.BindingContextChanged += OnBindingContextChanged;
        Bindable.ValueChanged += OnValueChanged;
    }

    protected override void OnDetachingFrom(Slider bindable)
    {
        base.OnDetachingFrom(bindable);
        Bindable.BindingContextChanged -= OnBindingContextChanged;
        Bindable.ValueChanged -= OnValueChanged;
        Bindable = null;
    }

    private void OnBindingContextChanged(object sender, EventArgs e)
    {
        OnBindingContextChanged();
        BindingContext = Bindable.BindingContext;
    }

    private void OnValueChanged(object sender, ValueChangedEventArgs e)
    {
        double value = Math.Round(e.NewValue);

        if (value != Math.Round(e.OldValue))
        {
            Command?.Execute(value.ToString());
        }

        Bindable.Value = value;
    }
}

} }

The error given to me whenever I navigate away from the page that is displaying this DataTemplate :每当我离开显示此DataTemplate的页面时,给我的错误:

System.ArgumentException: 'Value is an invalid value for Maximum
Parameter name: value'

The relevant portion of the callstack given to me when this exception is thrown:抛出此异常时提供给我的调用堆栈的相关部分:

    0xFFFFFFFFFFFFFFFF in System.Diagnostics.Debugger.Mono_UnhandledException_internal  
0x1 in System.Diagnostics.Debugger.Mono_UnhandledException at /Users/builder/jenkins/workspace/archive-mono/2020-02/android/release/mcs/class/corlib/System.Diagnostics/Debugger.cs:125,4   
0x26 in Android.Runtime.DynamicMethodNameCounter.148    
0xBA in Xamarin.Forms.BindableObject.SetValueCore at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:368,5    
0x121 in Xamarin.Forms.Internals.TypedBinding<Common.Models.AnalogSetting,double>.ApplyCore at D:\a\1\s\Xamarin.Forms.Core\TypedBinding.cs:218,5    
0x5D in Xamarin.Forms.Internals.TypedBinding<Common.Models.AnalogSetting,double>.Apply at D:\a\1\s\Xamarin.Forms.Core\TypedBinding.cs:135,4 
0x51 in Xamarin.Forms.BindableObject.ApplyBindings at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:480,5   
0x5D in Xamarin.Forms.BindableObject.SetInheritedBindingContext at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:209,4  
0x2 in Xamarin.Forms.Element.SetChildInheritedBindingContext at D:\a\1\s\Xamarin.Forms.Core\Element.cs:470,4    
0x8 in Xamarin.Forms.Element.<OnBindingContextChanged>b__82_0 at D:\a\1\s\Xamarin.Forms.Core\Element.cs:308,5   
0x2F in Xamarin.Forms.BindableObjectExtensions.PropagateBindingContext<Xamarin.Forms.Element> at D:\a\1\s\Xamarin.Forms.Core\BindableObjectExtensions.cs:28,5   
0x13 in Xamarin.Forms.Element.OnBindingContextChanged at D:\a\1\s\Xamarin.Forms.Core\Element.cs:306,4   
0x7 in Xamarin.Forms.VisualElement.OnBindingContextChanged at D:\a\1\s\Xamarin.Forms.Core\VisualElement.cs:812,4    
0xD in Xamarin.Forms.View.OnBindingContextChanged at D:\a\1\s\Xamarin.Forms.Core\View.cs:158,4  
0x10 in Xamarin.Forms.BindableObject.BindingContextPropertyChanged at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:500,4   C#
0x12E in Xamarin.Forms.BindableObject.SetValueActual at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:463,5 
0x17C in Xamarin.Forms.BindableObject.SetValueCore at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:397,5   
0x56 in Xamarin.Forms.BindableObject.SetValue at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:334,4    
0x5 in Xamarin.Forms.BindableObject.SetValue at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:311,68    
0x7 in Xamarin.Forms.BindableObject.set_BindingContext at D:\a\1\s\Xamarin.Forms.Core\BindableObject.cs:41,11   
0x13 in Xamarin.Forms.Platform.Android.TemplatedItemViewHolder.Recycle at D:\a\1\s\Xamarin.Forms.Platform.Android\CollectionView\TemplatedItemViewHolder.cs:38,4    
0x16 in Xamarin.Forms.Platform.Android.ItemsViewAdapter<Xamarin.Forms.GroupableItemsView,Xamarin.Forms.Platform.Android.IGroupableItemsViewSource>.OnViewRecycled at D:\a\1\s\Xamarin.Forms.Platform.Android\CollectionView\ItemsViewAdapter.cs:64,5    
0x32 in Xamarin.Forms.Platform.Android.SelectableItemsViewAdapter<Xamarin.Forms.GroupableItemsView,Xamarin.Forms.Platform.Android.IGroupableItemsViewSource>.OnViewRecycled at D:\a\1\s\Xamarin.Forms.Platform.Android\CollectionView\SelectableItemsViewAdapter.cs:53,4    
0x11 in 

A couple things:一些事情:

  1. OnDetachingFrom in my custom Behavior<Slider> class never gets called, even after the OnDisappearing function of the owning page is invoked我的自定义Behavior<Slider>类中的OnDetachingFrom永远不会被调用,即使在调用拥有页面的OnDisappearing函数之后
  2. I'm aware of the requirement to set the sliders Maximum value before the Minimum value.我知道在最小值之前设置滑块最大值的要求。 It's very possible the oddities of the Slider class is biting me here. Slider类的奇怪之处很可能在这里咬我。
  3. I believe the AnalogSetting model is being destroyed when the page is navigated away from, but the Behavior<Slider> class is still attempting to use the values that it bound to initially.我相信当页面被导航离开时, AnalogSetting模型正在被破坏,但Behavior<Slider>类仍在尝试使用它最初绑定的值。 I don't know this 100%, but it's my current guess.我不知道 100%,但这是我目前的猜测。

Debugging this has been a pain, since none of my code is in the callstack.调试这很痛苦,因为我的代码都没有在调用堆栈中。 Any tips on how to go about figuring out more information within the callstack would be appreciated.任何有关如何在调用堆栈中找出更多信息的提示将不胜感激。

I'm open to suggestions in regards to using something other than DataTemplateSelector and Behaviors to get what I'm after.我愿意接受关于使用DataTemplateSelectorBehaviors以外的东西来获得我想要的东西的建议。

We too had an issue with our sliders when it came to us using a DataTemplate, what we did is as follows: Since each DataTemplate is really just a glorified XAML element we can safely set a x:Name property on our slider and it will be unique and won't cause any conflicts during runttime/compile about non unique names.当我们使用 DataTemplate 时,我们的滑块也遇到了问题,我们所做的如下:由于每个 DataTemplate 实际上只是一个美化的 XAML 元素,我们可以安全地在滑块上​​设置x:Name属性,它将是唯一并且不会在运行时/编译期间导致任何关于非唯一名称的冲突。

So In our SliderTemplate.xaml we set a Max and Min所以在我们的 SliderTemplate.xaml 中,我们设置了一个最大值和最小值

    <Slider 
          x:Name="NoteSlider"
          Maximum="5"
          Minimum="0"
          ...
        />

Then in our SliderTemplate.xaml.cs:然后在我们的 SliderTemplate.xaml.cs 中:

  1. Define our view model we are using定义我们正在使用的视图模型

  2. Override OnBindingContextChanged to actually instantiate it覆盖 OnBindingContextChanged 以实际实例化它

  3. Set the correct min/max values.设置正确的最小/最大值。

    private MyViewModel controlModel;私有 MyViewModel 控制模型;

     public SliderInputTemplate() { InitializeComponent(); } protected override void OnBindingContextChanged() { base.OnBindingContextChanged(); controlModel = this.BindingContext as MyViewModel ; BindingContext = controlModel; } protected override void OnAppearing() { base.OnAppearing(); if(controlModel != null) { //controlModel.UpdateSlider(); if(controlModel.Max > controlModel.Min) { NoteSlider.Maximum = controlModel.Max; NoteSlider.Minimum = controlModel.Min; NoteSlider.Value = controlModel.SliderValue; } ... } }

I want to say the reason it throws that exception is because odds are the VM is disposed when you are navigating away, but the view is still sorta alive and thus it gets in a bad state.我想说它抛出该异常的原因是因为当您导航离开时,VM 可能已被处理,但视图仍然处于活动状态,因此它处于不良状态。 That is how we solved that issue我们就是这样解决这个问题的

I was receiving the same error when leaving the page.离开页面时我收到了同样的错误。 To fix it I added the FallbackValue parameter to the Maximum attribute in the XAML, and set it to a number greater than what any of my minimum numbers would possibly be.为了修复它,我将FallbackValue参数添加到 XAML 中的Maximum属性,并将其设置为大于我的任何最小数字可能的数字。

<Slider Maximum="{Binding Max, FallbackValue=1000000}" Minimum="{Binding Min}" Value="{Binding SettingValue}"></Slider>

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

相关问题 离开页面时记住级联下拉值 - Remember Cascading Dropdown value when navigating away from page 导航离开某个页面时执行c#命令 - Executing c# commands when navigating away from a certain page 离开一页时如何清除会话 - How to clear Session when navigating away from one page Xamarin,从另一个 class 获取 slider 的值 - Xamarin, getting value of slider from another class 导航离开主动加载 GridView 时无效的回发或回调参数 - Invalid postback or callback argument when navigating away from actively loading GridView 如何在xamarin crossplatform中单击按钮获取另一页面中滑块的值 - how to get the value of slider in another page with a button click in xamarin crossplatform 从C#(.Net 3.5)页面导航时调用方法的方法? - Way to call a method when navigating away from a page in C# (.Net 3.5)? 当用户按下Windows Phone返回键时,如何根据设置页面中的用户输入更新滑块的最大值? - How to update slider's maximum value based on user input in settings page when user presses Windows Phone back key? 如何在导航和返回页面时保留文本字段数据 - How to keep textfield data when navigating away and back to page 一旦 slider 达到最大值,尝试增加 WPF slider 的最大值 - Trying to increase the value of maximum of WPF slider once the slider reaches the maximum
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM