无法通过名称访问ListView的ViewCell中的开关/标签

时间:2019-06-03 14:10:40

标签: xamarin xamarin.forms

我已经使用Switch来切换数据,如果我添加一个事件就可以了。我试图删除数据绑定上的处理程序,以便事件处理程序保持不变。但是我并没有获得它的名字。

<ListView Grid.Column="2" x:Name="DynamicListView" IsPullToRefreshEnabled="False" ItemSelected="DynamicListViewItemSelected" IsVisible="false" WidthRequest="380" RowHeight="75">
<ListView.ItemTemplate>
     <DataTemplate>
          <ViewCell>
               <StackLayout Orientation ="Horizontal" >
                   <Label x:Name="configLabel" Text="{Binding Name}" HorizontalOptions="StartAndExpand" Style="{StaticResource BigBlackLabelLeft}"  />
                   <Switch x:Name="configSwitch" HorizontalOptions="End" OnColor="LightSeaGreen" IsToggled="{Binding IsVisible}" Toggled="HandleSwitchToggledByUser" />
               </StackLayout>
           </ViewCell>
      </DataTemplate>
</ListView.ItemTemplate>
</ListView>

因此,在后面的代码中,我尝试通过configLabel / configSwitch访问“标签/切换”,但是我在输入The name configSwitch does not exist on the current context时遇到错误。我不确定这里出了什么问题。

2 个答案:

答案 0 :(得分:1)

如果ViewCell中只有两个子视图,我将以这种方式访问​​该控件:

首先,我创建了一个自定义mySwitch并向其中添加了可绑定的属性name,稍后您可以使用该名称来确定要切换的switch

    public class mySwitch : Switch
    {

        public static readonly BindableProperty nameProperty =
  BindableProperty.Create("name", typeof(string), typeof(MainPage), null);

        public string name
        {
            get { return (string)GetValue(nameProperty); }
            set { SetValue(nameProperty, value); }
        }
    }

在xaml中,我以一个listView为例,并将绑定到switch的名称设置为与label文本相同:

<ContentPage.Content>

    <ListView>
        <ListView.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>wifi</x:String>
                <x:String>sound</x:String>
            </x:Array>
        </ListView.ItemsSource>

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout BackgroundColor="#eee" Orientation="Vertical">
                        <StackLayout Orientation="Horizontal">
                            <Label Text="{Binding .}" TextColor="#f35e20" />
                            <local:mySwitch name="{Binding .}"  HorizontalOptions="End" OnColor="LightSeaGreen" IsToggled="{Binding IsVisible}" Toggled="Switch_Toggled" />
                        </StackLayout>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

</ContentPage.Content>

在后面的代码中,您可以通过sender访问交换机,通过sender.parent访问ParentStackLayout,并通过(Label)ParentStackLayout.Children[0]访问标签,然后使用switch的名称来区分switch和更改相应的文本  configLabel:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    private void Switch_Toggled(object sender, ToggledEventArgs e)
    {
        // access switch
        var Switch_ToggledHandler = (mySwitch)sender;

        // access Parent Layout for Sender  
        StackLayout ParentStackLayout = (StackLayout)Switch_ToggledHandler.Parent;

        // access the Label "configLabel"  
        Label configLabel = (Label)ParentStackLayout.Children[0];


        if (Switch_ToggledHandler.IsToggled)
        {
            switch (Switch_ToggledHandler.name)
            {
                case "wifi":
                    configLabel.Text = "wifi open";
                    break;
                case "sound":
                    configLabel.Text = "sound is open";
                    break;
                default:
                    Console.WriteLine("Default case");
                    break;
            }

        }
        else {

            switch (Switch_ToggledHandler.name)
            {
                case "wifi":
                    configLabel.Text = "wifi off";
                    break;
                case "sound":
                    configLabel.Text = "sound is off";
                    break;
                default:
                    Console.WriteLine("Default case");
                    break;
            }
        }
    }
}

这是一个gif:

gif

我还上传了演示here,您可以检查它。让我知道它是否对您有用。

答案 1 :(得分:0)

如果要在切换事件中获取ViewCell的BindingContext,这非常简单:只需将sender参数转换为View,并将其BindingContext转换为列表中显示的项目的类,然后从中读取值您需要的:

    private void HandleSwitchToggledByUser(object sender, ToggledEventArgs e)
    {
        if (sender is View v && v.BindingContext is ItemClass item)
        {
            var switchName = item.Name;
        }
    }