XAMARIN中的Handel多个开关按钮

时间:2017-12-15 17:19:25

标签: xamarin.forms

我有一个要求(在XAMARIN中)从100s开关盒中捕获100次切换动作并记住。因此,当我加载应用程序时,它会记住每个Switch框的状态。到目前为止我创建的是一个自定义的BindableProperty,所​​以我可以重复使用它们。 这是我到目前为止所做的:

public static readonly BindableProperty LabelProperty =BindableProperty.Create("Label", typeof(string), typeof(CustomSwitchCell));
    public string Label
    {
       get
        {
            return (string)GetValue(LabelProperty);
        }
        set
        {
            SetValue(LabelProperty, value);
        }
    }

在XAML文件中

<Label Text="{Binding Label}" IsVisible="True"   Grid.Row="0" Grid.Column="0" HorizontalOptions="StartAndExpand"    />
    <Switch x:Name="SwitchName" IsToggled="{Binding ItemSwitch}"  Toggled="OnFavoriteClicked"  Grid.Row="0" Grid.Column="1" HorizontalOptions="EndAndExpand"   />

现在我在主页中使用自定义单元格,如

<switch:CustomSwitchCell Label="Item1" />
<switch:CustomSwitchCell Label="Item2"/>
<switch:CustomSwitchCell Label="Item3"/>
<switch:CustomSwitchCell Label="Item4"/>

现在它创建了多个带有Lable的Switch按钮,但我不知道如何获得

  

已切换=&#34; OnFavoriteClicked&#34;对于他们每个人。   有没有其他简单的方法来获取多个切换操作并存储它并在页面加载时加载而不创建这么多的功能?   希望这澄清......请指导..我是XAMARIN的新蜜蜂..   谢谢,   MKJ

3 个答案:

答案 0 :(得分:0)

您将需要像sqllite这样的本地数据库。我大部分时间都使用SQLite.Net.Core-PCL nuget。

public static class MyEnums
{
    On = 1,
    Off = 2,
    Unselected = 3
}

某种识别每个切换开关以供将来参考的方法,我假设他们有ID。

public class Model_MySwitchWidget
{
    [Table("mySwitchWidget")]

    [PrimaryKey, NotNull]
    private int switchID;
    private int selectionStatus;    
    private int switchText;

    public static GetAll()
    {
        using(var db = DependencyService.Get<ISQLite>().GetConnection())
        {
            return new ObservableCollection<Model_Model_MySwitchWidget>(db.Table<Model_MySwitchWidget>().ToList());
        } 

    }

public static GetByID(int searchedSwitchID)
{
     using(var db = DependencyService.Get<ISQLite>().GetConnection())
        {
            List<Model_MySwitchWidget> switches = 
            db.Query<ModelMySwitchWidget>("Select * FROM mySwitchWidget 
            Where switchID = ?", searchedSwitchID);
            return switches[0];
        } 
}

    public void InsertItem()
    {

         using (var db = DependencyService.Get<ISQLite>().GetConnection())
            {
                db.Insert(this);
            }
    }

    public void UpdateItem()
    {
         using (var db = DependencyService.Get<ISQLite>().GetConnection())
            {
                db.Update(this);
            }
    }
}

(在你的开关内)

private static void OnSelectedItemChanged(BindableObject bindable, object oldvalue, object newvalue)
{
    if(oldvalue != newvalue)
    {
        var existingmodel = Model_MySwitchWidget.GetByID(this.switchID);
        if(exstingmodel == null)
        {
              var newswitch = new Model_MySwitchWidget();
              newswitch.selectionStatus = newvalue;
              newswitch.switchID = this.switchID;
              newswitch.switchText = this.switchText;
              newswitch.InsertItem();              

        }
        else
        {
             existingmodel.selectionStatus = newvalue;
             existingmodel.UpdateItem();
        }
    } 

现在加载页面,viewmodel或其他任何内容

var mycollectionofswitches = new ObservableCollection<Model_MySwitchWidget>(Model.MySwitchWidget.GetAll());

你有一系列已保存的开关。

答案 1 :(得分:0)

我的方法看起来像这样:

<强>要求: James Montemango Settings Plugin 你也可以使用数据库,但我认为设置插件实现得更快,重量更轻,易于维护。它使用本机平台工具在设备上存储持久数据。还有一个很好的JSon序列化程序,用于将复杂模型序列化为字符串,因为Settings Plugin只能存储基本类型(int,bool,strings等) NewtonSoft JSon Serializer

创建一个继承自INotifyPropertyChanged Interface的模型类。 每个交换机单元都有一个模型作为它的绑定上下文。

public class YourModel : INotifyPropertyChanged
{
    private string labelText;
    private bool switchIsToggled;

    public string LabelText
    {
        get { return labelText; }
        set 
        { 
            labelText = value;
            OnPropertyChanged();
        }
    }

    public bool SwitchIsToggled
    {
        get { return switchIsToggled; }
        set 
        { 
            switchIsToggled = value;
            OnPropertyChanged();
        }
    }
}
  • 创建ViewModel
  • YourModel
  • 中创建公共数组,IList或ViewModel的ObservableCollection
  • 将页面的绑定上下文设置为ViewModel

现在有两种方法:您可以轻松创建ListView,然后将YourModel的集合分配给ListView的ItemsSource。 当您的ViewModel创建集合时,它可以遍历它并订阅每个SwitchIsToggled bool:

foreach(YourModel switchModel in YourModelList)
{
    switchModel.PropertyChanged += Switch_PropertyChanged;
}

private void Switch_PropertyChanged(object sender, PropertyChangedEventArgs args)
{
    if(sender is YourModel yourModel && args.PropertyName == SwitchIsToggled)
    {
        //code that should be called when switch was toggled
    }
}

如果您不想拥有可滚动列表,那么我会在页面上尝试此方法:

public class YourPage : ContentPage
{

    public YourPage()
    {
        BindingContext = YourViewModel;
    }

    protected override OnBindingContextChanged
    {
        if(BindingContext is YourViewModel vm)
        {
            var stackLayout = new StackLayout();
            foreach(var yourModel in vm.YourModelList)
            {
                stackLayout.Children.Add(new CustomSwitchCell() { BindingContext = yourModel; }

                //or with event (not suggested, stick to MVVM!)
                //var newCustomSwitchCell = new CustomSwitchCell() { BindingContext = yourModel }
                //newCustomSwitchCell.Toggled += YourToggledEvent;
                //stackLayout.Children.Add(newCustomSwitchCell);
            }
        }
    }
}

最后但并非最不重要的是,每次应用关闭时或任何时候:将视图模型中的集合与Newtonsoft JSon插件串行化为字符串,然后将其存储在Settings类中,由设置插件创建。

要恢复列表,只需反序列化设置类中以前序列化的字符串,然后重复此过程

看起来很多,但很容易维护,祝你好运!

答案 2 :(得分:0)

感谢您的好方法。 如上所述,我有一个Custom ViewCell。

<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="TODOListWithDB.Reusable.CustomSwitchCell">
<Grid BackgroundColor="Gold" Padding="13,0">
    <Grid.RowDefinitions>
        <RowDefinition Height="auto" />
    </Grid.RowDefinitions>
    <Label Text="{Binding Label}" IsVisible="True"   Grid.Row="0" Grid.Column="0" HorizontalOptions="StartAndExpand" />
    <Switch x:FieldModifier="public" x:Name="SwitchName"   Toggled="OnFavoriteClicked"  Grid.Row="0" Grid.Column="1" HorizontalOptions="EndAndExpand"   />
</Grid>

我可以多次在主页面中添加自定义ViewCell。

<TableSection Title="selectItems" x:Name="ParentTableSelection"><Switch:CustomSwithCell Label="item1"/><Switch:CustomSwithCell Label="Item2" />.....

当我切换到交换机时,它将项目名称保存到DB(而不是切换操作)。下次我加载应用程序的时候我检查如果名称已经存在于DB上,或者通过迭代表格部分为每个如果项目名称存在,那么Switch的状态为on,否则Switch为Off ..不确定这是否是最好的方法。感谢您采用不同的方法......