.net Maui XAML绑定在集合中找不到属性

zysjyyx4  于 2023-01-14  发布在  .NET
关注(0)|答案(1)|浏览(253)

我正在编写一个maui桌面应用程序视图,它基于集合中的项目生成块。所以我有一个可观察的集合,称为Pedals,我希望ListView枚举通过它,并基于我定义的模板生成一个ViewCell,所有这些都工作正常。然而在我的ViewCell中,数据绑定似乎找不到它们正在用于表示的项目。
我的例子应该有两个对象在踏板混响踏板对象和失真踏板对象(两个可观察的对象与可观察的属性)和我的模板应该加载一个模板混响和另一个失真。
在混响踏板失真块中,我无法访问类的属性。每个踏板对象都继承自带有参数属性的接口。这里是我的xaml代码片段,目前调试起来一团糟,但你可以看到我尝试过的所有不同的东西

<ListView x:Name="listView" ItemsSource="{Binding Pedals}" SelectedItem="{Binding SelectedPedal, Mode=TwoWay}"  >
        <ListView.ItemTemplate>
            <templates:PedalDataTemplateSelector>
                <templates:PedalDataTemplateSelector.SchroederReverbPedalTemplate BindingContext="{Binding .}">
                    <DataTemplate>
                        <ViewCell x:Name="parameterControls">
                            <StackLayout Orientation="Vertical">
                                <Slider x:Name="delaySlider" Value="{Binding Path=ObservableParameters[Delay]}" Minimum="0" Maximum="1500"/>
                                <Label x:Name="delaySlidervalueLabel" Text="{Binding Value, Source={x:Reference delaySlider}, StringFormat='{0:F1}'}"/>
                                <Label Text="{Binding .}"/>
                                <Label Text="{Binding Path=item.ObservableParameters[Delay], Source={RelativeSource AncestorType={x:Type DataTemplate}}}"/>
                                <Label Text="Delay"/>
                                <Label Text="Decay"/>
                                <Slider x:Name="decaySlider" Value="{Binding ObservableParameters[Decay], Source={x:Reference listView}}" Minimum="0" Maximum="1000"/>
                                <Label x:Name="decaySlidervalueLabel" Text="{Binding Value, Source={x:Reference decaySlider}, StringFormat='{0:F1}'}"/>

                                <Label Text="Mix %"/>
                                <Slider x:Name="mixSlider" Value="{Binding ObservableParameters[MixPercent], Source={x:Reference listView}}" Minimum="0" Maximum="100"/>
                                <Label x:Name="mixSlidervalueLabel" Text="{Binding Value, Source={x:Reference mixSlider}, StringFormat='{0:F1}'}"/>
                                <Switch IsToggled="{Binding IsEnabled, Source={x:Reference listView}}" OnColor="Pink" ThumbColor="Purple"/>
                                <Button Text="Print Debug" Command="{Binding Source={RelativeSource AncestorType={x:Type viewmodel:PedalBoardViewModel}}, Path=PrintDebugCommand}" />
                            </StackLayout>

我不确定这是否有帮助,但这是我的datatemplateselecetor的代码,以防出现错误

public class PedalDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate SchroederReverbPedalTemplate { get; set; }
    public DataTemplate OverDrivePedalTemplate { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        var viewCell = new ViewCell();

        if (item is SchroederReverb)
        {
            return SchroederReverbPedalTemplate;
        }
        else if (item is OverDriveDistortion)
        {
            viewCell.BindingContext = item;
            return OverDrivePedalTemplate;
        }

        return null;
    }
}

我已经尝试了所有的方法,我认为我有一个解决方案使用SelectedPedal,但当一个以上的踏板被使用时,它会崩溃,因为它开始同步编辑它们的所有值。我不知道还能尝试什么,我已经尝试将列表视图设置为相对源,无论如何,它似乎找不到对象。
我唯一的线索是测试Bind的源代码时使用的空标签,执行{Binding .}可以得到正确的对象,但我无法让它使用滑块的相同数据上下文。(执行Just {Binding Parameters}会引发无法找到绑定在视图模型上的参数的错误。我还确保我尝试绑定的所有对象都是可观察的属性。
最后这里是我的模型代码,踏板是IPEDAL类型的集合,我不得不为我的混响踏板基类写一个可观察的 Package 器,但这个 Package 器包括所有相关的信息,基类只是有运行混响算法的方法。基类包含一个参数字典,并实现IPEDAL,我只是用这个类来 Package 那些可观察的

public partial class ObservableSchroederReverb : SchroederReverb
    {

        public Dictionary<string, float> ObservableParameters
        {
            get => Parameters;
            set
            {
                Debug.WriteLine($"Chaning to {value}");
                SetProperty(Parameters, value, this, (u, n) => u.Parameters = n);
            }
        }
        public ObservableSchroederReverb(IAudioData audioFile, float delay, float decay, float mixPercent) : base(audioFile, delay, decay, mixPercent)
        {
            {
                Parameters = new Dictionary<string, float>()
                {
                    { "Delay", delay },
                    { "Decay", decay },
                    { "MixPercent", mixPercent }
                };
                Delay = delay;
                Decay = decay;
                MixPercent = mixPercent;
                AudioFile = audioFile;
                IsEnabled = false;
            }
        }
    }
ovfsdjhp

ovfsdjhp1#

这条线

x:DataType="viewmodel:PedalBoardViewModel"

告诉VS该页的VM类型为PedalBoardViewModel。它纯粹是Intellisense的帮助器方法,不是必需的。但是,如果您有它,它会认为该页上的所有绑定表达式都是该VM的属性。当您有ListView之类的模板化视图时,这是一个问题。因为模板将具有与页面的其余部分不同的BindingContextIPedal)。
您可以通过向您的DataTemplate添加另一个DataType来解决此问题,如下所示

x:DataType="viewmodel:IPedal"

但是,在您情况下,这不会有帮助,因为您希望使用IPedal上不存在的属性
因此,对于这种特定情况,答案是完全删除DataType
然后可以在绑定表达式中使用它

Value="{Binding ObservableParameters[Decay]}"

您不需要指定源

相关问题