मेरे पास यह एक्सएएमएल है जो 6 टेक्स्टसेल प्रदर्शित करता है जो चेक मार्क दिखा सकता है या नहीं। वे सक्षम या सक्षम नहीं होने के कारण भी:

<TableSection Title="Front Side" x:Name="cfsSection">
   <local:CustomTextCell Text="{Binding [0].Name}" IsChecked="{Binding [0].IsSelected}" IsEnabled="{Binding [0].IsSelected, Converter={StaticResource InverseBoolConverter} } "Tapped="cfsSelectValue"/>
   <local:CustomTextCell Text="{Binding [1].Name}" IsChecked="{Binding [1].IsSelected}" IsEnabled="{Binding [1].IsSelected, Converter={StaticResource InverseBoolConverter} } "Tapped="cfsSelectValue"/>
   <local:CustomTextCell Text="{Binding [2].Name}" IsChecked="{Binding [2].IsSelected}" IsEnabled="{Binding [2].IsSelected, Converter={StaticResource InverseBoolConverter} } "Tapped="cfsSelectValue"/>
   <local:CustomTextCell Text="{Binding [3].Name}" IsChecked="{Binding [3].IsSelected}" IsEnabled="{Binding [3].IsSelected, Converter={StaticResource InverseBoolConverter} } "Tapped="cfsSelectValue"/>
   <local:CustomTextCell Text="{Binding [4].Name}" IsChecked="{Binding [4].IsSelected}" IsEnabled="{Binding [4].IsSelected, Converter={StaticResource InverseBoolConverter} } "Tapped="cfsSelectValue"/>
   <local:CustomTextCell Text="{Binding [5].Name}" IsChecked="{Binding [5].IsSelected}" IsEnabled="{Binding [5].IsSelected, Converter={StaticResource InverseBoolConverter} } "Tapped="cfsSelectValue"/>
</TableSection>

पीछे कोड मुझे लगता है कि काफी सरल है। यह SSVViewModel की एक सरणी घोषित करता है और बाध्यकारी पाठ को प्रदर्शित करने का कारण बनता है:

    SSVViewModel[] CFS = new[] {
        new SSVViewModel {Id = 0, Name=LANG.English.Text(), IsSelected = false},
        new SSVViewModel {Id = 1, Name=LANG.Romaji.Text(), IsSelected = false},
        new SSVViewModel {Id = 2, Name=LANG.Kana.Text(), IsSelected = false},
        new SSVViewModel {Id = 3, Name=LANG.Kanji.Text(), IsSelected = false},
        new SSVViewModel {Id = 4, Name=LANG.KanjiKana.Text(), IsSelected = false},
        new SSVViewModel {Id = 5, Name=LANG.KanaKanji.Text(), IsSelected = false},
    };

जब किसी सेल पर क्लिक किया जाता है तो इस फ़ंक्शन को कहा जाता है:

void cfsSelectValue(object sender, EventArgs e) 
{
        var cell = sender as TextCell;
        if (cell == null)
            return;

        var selected = cell.Text;

        foreach (var setting in CFS)
            setting.IsSelected = false;

        foreach (var setting in CFS)
            if (setting.Name == selected)
                setting.IsSelected = true;

 }

हालाँकि जब पहले दो सेल में से किसी एक पर क्लिक किया जाता है तो दोनों चेक के रूप में दिखाई देते हैं। अन्य सभी सेल क्लिक ठीक काम करते हैं। मेरे कोड के दूसरे भाग में मैं एक समान निर्माण का उपयोग करता हूं और यह अंतिम दो कक्ष हैं जो काम नहीं करते हैं।

ध्यान दें कि IsEnabled काम करता है लेकिन Ischecked नहीं

क्या कोई देख सकता है कि पहली दो कोशिकाओं पर एक क्लिक संभवतः कोई समस्या क्यों दे सकता है। मैं कई बार डीबगर के साथ इसके माध्यम से रहा हूं लेकिन मैं अभी भी नहीं देख सकता कि क्या गलत हो सकता है। निश्चित रूप से कोड जो IsSelected को गलत पर सेट करता है, उसे एक सेल को छोड़कर सभी को चेक के रूप में दिखाना चाहिए।

ध्यान दें कि इस लाइन को डीबग करते समय: settings.IsSelected = false; और यह पंक्ति: सेटिंग.IsSelected = true; तो सब कुछ वैसा ही प्रकट होता है जैसा कि सही सेल में होना चाहिए, इसका चयन सही पर सेट है और अन्य गलत हैं। जब मैं डिस्प्ले को देखता हूं तो ऐसा लगता है कि बाइंडिंग उन पहले दो सेल के लिए काम नहीं कर रही थी।

मैं जिस मॉडल कोड का उपयोग कर रहा हूं वह यहां दिया गया है:

public class SSVViewModel: ObservableProperty
{
    private int id;
    private string name;
    private bool isSelected;

    public int Id
    {
        get
        {
            return id;
        }
        set
        {
            if (value != id)
            {
                id = value;
                NotifyPropertyChanged("Id");
            }
        }
    }

    public string Name
    {
        get
        {
            return name;
        }
        set
        {
            if (value != name)
            {
                name = value;
                NotifyPropertyChanged("Name");
            }
        }
    }

    public bool IsSelected
    {
        get
        {
            return isSelected;
        }
        set
        {
            if (value != isSelected)
            {
                isSelected = value;
                NotifyPropertyChanged("IsSelected");
            }
        }
    }
}

यहाँ CustomTextCellRenderer के लिए कोड है

public class CustomTextCellRenderer : TextCellRenderer
{
    UITableViewCell _nativeCell;

    public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
    {
        _nativeCell = base.GetCell(item, reusableCell, tv);
        var formsCell = item as CustomTextCell;

        if (formsCell != null)
        {
            formsCell.PropertyChanged -= OnPropertyChanged;
            formsCell.PropertyChanged += OnPropertyChanged;
        }

        SetCheckmark(formsCell);
        SetTap(formsCell);

        return _nativeCell;
    }

    void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        var formsCell = sender as CustomTextCell;
        if (formsCell == null)
            return;

        if (e.PropertyName == CustomTextCell.IsCheckedProperty.PropertyName)
        {
            SetCheckmark(formsCell);
        }

        if (e.PropertyName == CustomTextCell.NoTapProperty.PropertyName)
        {
            SetTap(formsCell);
        }
    }

    private void SetCheckmark(CustomTextCell formsCell)
    {
        if (formsCell.IsChecked)
            _nativeCell.Accessory = UITableViewCellAccessory.Checkmark;
        else
            _nativeCell.Accessory = UITableViewCellAccessory.None;
    }

    private void SetTap(CustomTextCell formsCell)
    {
        if (formsCell.NoTap)
            _nativeCell.SelectionStyle = UITableViewCellSelectionStyle.None;
        else
            _nativeCell.SelectionStyle = UITableViewCellSelectionStyle.Default;
    }

}

अपडेट 1

<local:CustomTextCell           Text="{Binding [0].Name}" IsChecked="{Binding [0].IsSelected}" Tapped="cfsSelectValue" CommandParameter="0" />
<local:CustomTextCell           Text="{Binding [1].Name}" IsChecked="{Binding [1].IsSelected}" Tapped="cfsSelectValue" CommandParameter="1" />
<local:CustomTextCell           Text="{Binding [2].Name}" IsChecked="{Binding [2].IsSelected}" Tapped="cfsSelectValue" CommandParameter="2" />
<local:CustomTextCell           Text="{Binding [3].Name}" IsChecked="{Binding [3].IsSelected}" Tapped="cfsSelectValue" CommandParameter="3" />
<local:CustomTextCell           Text="{Binding [4].Name}" IsChecked="{Binding [4].IsSelected}" Tapped="cfsSelectValue" CommandParameter="4" />

चूंकि प्रश्न लिखा गया था, मैंने लैंग चयन के लिए इसका उपयोग करना बंद कर दिया है, हालांकि यह अभी भी कोड के दूसरे भाग में उपयोग किया जाता है और मैंने कुछ डीबग पॉइंट डालने की कोशिश की। यहाँ मैंने क्या किया है:

मैंने इसे आईओएस कस्टम रेंडरर में जोड़ा:

    private void SetCheckmark(CustomTextCell formsCell)
    {
        if (formsCell.IsChecked)
        {
            _nativeCell.Accessory = UITableViewCellAccessory.Checkmark;
            Debug.WriteLine(_nativeCell.TextLabel.Text + " checked");
        }
        else
        {
            _nativeCell.Accessory = UITableViewCellAccessory.None;
            Debug.WriteLine(_nativeCell.TextLabel.Text + " unchecked");
        }
    }

जब मैंने JLPT N2 पर क्लिक किया तो यह परिणाम है:

Category Group unchecked
Category unchecked
All Available Words unchecked
Japanese for Busy People 1 unchecked
Japanese for Busy People 2 unchecked
Japanese for Busy People 3 unchecked
JLPT Level N5 unchecked
JLPT Level N4 unchecked
JLPT Level N3 unchecked
JLPT Level N2 unchecked
JLPT Level N1 checked
JLPT Level N2 checked
JLPT Level N3 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N2 checked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked
JLPT Level N1 unchecked

यह बिल्कुल भी नहीं था जिसकी मुझे उम्मीद थी।

स्क्रीन पर मैं देखता हूं कि अपेक्षित N2 अक्षम है लेकिन N3 और N2 के बगल में एक चेक मार्क है।

सुनिश्चित नहीं है कि यह मदद करता है लेकिन मुझे लगता है कि आईओएस रेंडरर कोड इस्तेमाल किया गया है जो अन्य स्थानों में उपयोग किए गए समान कोड से अलग है। उदाहरण के लिए यहां एक अलग आईओएस रेंडरर है। कोड बहुत अलग दिखता है। मुझे एहसास है कि कार्य अलग है लेकिन इसमें cell = tv.DequeueReusableCell(fullName) as CellTableViewCell; जैसी चीजें हैं

public class TextCellCustomRenderer : TextCellRenderer
{
    CellTableViewCell cell;
    public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
    {
        var textCell = (TextCell)item;
        var fullName = item.GetType().FullName;
        cell = tv.DequeueReusableCell(fullName) as CellTableViewCell;

        if (cell == null)
        {
            cell = new CellTableViewCell(UITableViewCellStyle.Value1, fullName);
        }
        else
        {
            cell.Cell.PropertyChanged -= cell.HandlePropertyChanged;
            //cell.Cell.PropertyChanged -= Current_PropertyChanged;
        }

        cell.Cell = textCell;
        textCell.PropertyChanged += cell.HandlePropertyChanged;
        cell.PropertyChanged = this.HandlePropertyChanged;
        cell.SelectionStyle = UITableViewCellSelectionStyle.None;
        cell.TextLabel.Text = textCell.Text;
        cell.DetailTextLabel.Text = textCell.Detail;
        cell.ContentView.BackgroundColor = UIColor.White;


        switch (item.StyleId)
        {
            case "checkmark":
                cell.Accessory = UIKit.UITableViewCellAccessory.Checkmark;
                break;
            case "detail-button":
                cell.Accessory = UIKit.UITableViewCellAccessory.DetailButton;
                break;
            case "detail-disclosure-button":
                cell.Accessory = UIKit.UITableViewCellAccessory.DetailDisclosureButton;
                break;
            case "disclosure":
                cell.Accessory = UIKit.UITableViewCellAccessory.DisclosureIndicator;
                break;
            case "none":
            default:
                cell.Accessory = UIKit.UITableViewCellAccessory.None;
                break;
        }

        //UpdateBackground(cell, item);

        return cell;
    }

    void checkAccessoryVisibility() {

    }

}
6
Alan2 3 नवम्बर 2017, 12:17

2 जवाब

सबसे बढ़िया उत्तर

लॉग स्टेटमेंट के अनुसार, ऐसा लगता है कि प्रॉपर्टी-चेंज-हैंडलर के लिए अनसब्सक्राइब लॉजिक उम्मीद के मुताबिक काम नहीं कर रहा है।

TextCellRenderer के साथ, हमें स्पष्ट रूप से संपत्ति-परिवर्तित-ईवेंट की सदस्यता लेने की आवश्यकता नहीं है क्योंकि एक आधार ओवरराइड करने योग्य विधि HandlePropertyChanged है जिसका इस संदर्भ में पुन: उपयोग किया जा सकता है।

इस विधि का उपयोग करने के लिए रेंडरर कोड को बदलना (इस उत्तर के समान) से इस समस्या का समाधान होने की उम्मीद है:

public class CustomTextCellRenderer : TextCellRenderer
{
    public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
    {
        var nativeCell = base.GetCell(item, reusableCell, tv);

        if (item is CustomTextCell formsCell)
        {
            SetCheckmark(nativeCell, formsCell);
            SetTap(nativeCell, formsCell);
        }

        return nativeCell;
    }

    protected override void HandlePropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        base.HandlePropertyChanged(sender, args);

        System.Diagnostics.Debug.WriteLine($"HandlePropertyChanged {args.PropertyName}");

        var nativeCell = sender as CellTableViewCell;
        if (nativeCell?.Element is CustomTextCell formsCell)
        {
            if (args.PropertyName == CustomTextCell.IsCheckedProperty.PropertyName)
                SetCheckmark(nativeCell, formsCell);
            else if (args.PropertyName == CustomTextCell.NoTapProperty.PropertyName)
                SetTap(nativeCell, formsCell);
        }
    }

    void SetCheckmark(UITableViewCell nativeCell, CustomTextCell formsCell)
    {
        if (formsCell.IsChecked)
            nativeCell.Accessory = UITableViewCellAccessory.Checkmark;
        else
            nativeCell.Accessory = UITableViewCellAccessory.None;
    }

    void SetTap(UITableViewCell nativeCell, CustomTextCell formsCell)
    {
        if (formsCell.NoTap)
            _nativeCell.SelectionStyle = UITableViewCellSelectionStyle.None;
        else
            _nativeCell.SelectionStyle = UITableViewCellSelectionStyle.Default;
    }
}
5
Sharada Gururaj 13 नवम्बर 2017, 15:32

कोड मेरे लिए सही दिखता है - ऐसा होने का एकमात्र कारण मुझे लगता है कि स्ट्रिंग तुलना तर्क अपेक्षित रूप से काम नहीं कर रहा है।

शायद एक संदर्भ आधारित तुलना इस मुद्दे को हल कर सकती है। यानी अपना एक्सएएमएल इसमें बदलें:

<TableSection Title="Front Side" x:Name="cfsSection">
   <local:CustomTextCell BindingContext="{Binding [0]}" Text="{Binding Name}" IsChecked="{Binding IsSelected}" Tapped="cfsSelectValue"/>
   <local:CustomTextCell BindingContext="{Binding [1]}" Text="{Binding Name}" IsChecked="{Binding IsSelected}" Tapped="cfsSelectValue"/>
   <local:CustomTextCell BindingContext="{Binding [2]}" Text="{Binding Name}" IsChecked="{Binding IsSelected}" Tapped="cfsSelectValue"/>
   <local:CustomTextCell BindingContext="{Binding [3]}" Text="{Binding Name}" IsChecked="{Binding IsSelected}" Tapped="cfsSelectValue"/>
   <local:CustomTextCell BindingContext="{Binding [4]}" Text="{Binding Name}" IsChecked="{Binding IsSelected}" Tapped="cfsSelectValue"/>
   <local:CustomTextCell BindingContext="{Binding [5]}" Text="{Binding Name}" IsChecked="{Binding IsSelected}" Tapped="cfsSelectValue"/>
</TableSection>

और टैप किए गए हैंडलर को:

void cfsSelectValue(object sender, EventArgs e)
{
    var cell = sender as TextCell;
    if (cell == null)
        return;

    var selected = cell.BindingContext;

    foreach (var setting in CFS)
        setting.IsSelected = (setting == selected);

}
5
Aleks Andreev 28 नवम्बर 2017, 21:59