2017-01-14 7 views
16

मैं निम्नलिखित लेबल:Xamarin में एक से अधिक लेबल जोड़ें फॉर्म्स

<Label Text="{x:Static local:FontAwesome.FACheck}" FontFamily="FontAwesome" TextColor="Green"/> 

और बटन पर एक घटना:

correctButton.Clicked += (sender, e) => 
{ 
    App.DB.IncrementScore(); 
}; 

क्या करता है हर मैं एक बटन मेरी स्कोर से वृद्धि की जाती है पर क्लिक करें 1. मैं जो करना चाहता था वह भी स्कोर की संख्या के आधार पर Label एस की संख्या में वृद्धि करता है।

enter image description here

किसी को भी किसी भी विचार मैं यह कैसे प्राप्त कर सकते है: नीचे संलग्न छवि देखते हैं?

+2

मैं दृढ़ता से इस एप्लिकेशन के लिए एक MVVM वास्तुकला में देख सिफारिश करेंगे। आप अपने लेबल को अपने ViewMidel में 'ObservableCollection ' पर बाध्य कर सकते हैं। –

+1

@RobLyndon धन्यवाद।मैं एमवीवीएम के बारे में जानता हूं लेकिन मुझे नहीं पता कि इसे यहां कैसे लागू किया जाए। क्या आप मुझे मेरे मुद्दे से संबंधित कुछ कोड नमूना दे सकते हैं? –

उत्तर

7

इस सवाल का विभिन्न समाधान कर रहे हैं। एक को चुनने से पहले उनमें से सभी के माध्यम से पढ़ लें - मेरी पसंदीदा (सरलतम एक) सभी तरह नीचे सूचीबद्ध है ...

कार्य # 1:

के रूप में कई लोगों ने सुझाव दिया है, आप कर सकते हैं

public class MyViewModel() 
{ 
    public ObservableCollection<int> Items { get; set; } = new ObservableCollection<int>(); 
} 

private MyViewModel _viewModel = new MyViewModel(); 
public MainPage() 
{ 
    InitializeComponent(); 

    BindingContext = _viewModel; 
} 

correctButton.Clicked += (sender, e) => 
{ 
    App.DB.IncrementScore(); 
    _viewModel.Items.Add(0); 
}; 
: कुछ संग्रह नियंत्रण (मुझे लगता है कि एक पल में करने के लिए आया हूँ), एक ViewModel के भीतर एक ObservableCollection परिभाषित करते हैं, पृष्ठ के Binding Context कि ViewModel का एक उदाहरण के लिए सेट, और बटन पर क्लिक संग्रह में आइटम जोड़ने बनाने

ObservableCollection एसी का प्रकार tually कोई प्रभाव नहीं पड़ेगा, क्योंकि हम सभी वस्तुओं के लिए एक ही स्थिर ItemTemplate उपयोग कर रहे हैं:

<ContentPage.Resources> 
    <DataTemplate x:Key="ScoreItemTemplate"> 
     <ViewCell> 
      <ViewCell.View> 
       <Label Text="{x:Static local:FontAwesome.FACheck}" FontFamily="FontAwesome" TextColor="Green"/> 
      </ViewCell.View> 
     </ViewCell> 
    </DataTemplate> 
</ContentPage.Resources> 

इस दृष्टिकोण के साथ मुख्य समस्या यह है कि Xamarin.Forms ListView अपने आइटम क्षैतिज प्रदर्शित नहीं कर सकता है। इसका मतलब यह है, तुम वहाँ बाहर उपलब्ध HorizontalListView Nuget संकुल में से एक डाउनलोड करें, या built-in (only in Xamarin.Forms 2.3 and above!) CarouselView उपयोग करने की आवश्यकता होगी: के माध्यम से स्वाइप के लिए सभी दृश्य प्रभावों को दूर करने के लिए कुछ समय बिताने के लिए, आप चाहें तो कर सकते हैं करेंगे तो

<CarouselView ItemTemplate="{StaticResource ScoreItemTemplate}" ItemsSource="{Binding Items}"/> 

कैरोसेल, और आइटम चुनने के लिए यदि आप एक क्षैतिज ListView का उपयोग करना चुनते हैं ...

कार्य # 2:

इसके बजाय, वहाँ दो वैकल्पिक समाधान है कि कम प्रयास करना शामिल होता है

जाहिर है, सरल दृष्टिकोण कोड में "टेम्पलेट" लेबल बनाने के लिए होगा:

<StackLayout Orientation="Horizontal" x:Name="LabelStack"/> 
:
private Label CreateScoreLabel() 
{ 
    return new Label {Text = FontAwesome.FACheck, TextColor = Color.Green, FontFamily = "FontAwesome"}; 
} 

... पृष्ठ पर एक क्षैतिज StackLayout जोड़ने

... और नए लेबल मुश्किल तरीके से जोड़ें:

correctButton.Clicked += (sender, e) => 
{ 
    App.DB.IncrementScore(); 
    LabelStack.Children.Add(CreateScoreLabel()); 
}; 

बहरहाल, यह सब नहीं बल्कि सिर्फ हरे चेक अंक की एक सूची बनाने के लिए hacky लगता है। यह करने के लिए हमें ले जाता है ...

... दृष्टिकोण # 3:

तकनीकी तौर पर, यह नहीं वास्तव में आप के लिए क्या पूछा (वेतन वृद्धि लेबल की संख्या), लेकिन अपनी स्क्रीन के अनुसार शॉट यह आपकी आवश्यकताओं को एक बहुत ही सरल तरीके से पूरा कर सकता है।

मौजूदा लेबल का पाठ निकालें (के रूप में यह स्टार्टअप पर कुछ भी नहीं प्रदर्शित करेगा), और बजाय इसे एक अनन्य नाम देना:

<Label x:Name="ScoreLabel" FontFamily="FontAwesome" TextColor="Green"/> 

अब, string प्रकार है कि किसी दिए गए स्ट्रिंग को दोहराता के लिए एक सरल विस्तार विधि को परिभाषित समय की एक निश्चित संख्या के लिए:

public static class StringExtensions 
{ 
    public static string Repeat(this string input, int num) 
    { 
     return String.Concat(Enumerable.Repeat(input, num)); 
    } 
} 

(इस दोहराने समारोह संभव के रूप में performant बनाने के लिए कई तरीके हैं, मैं बस सरलतम एक लाइनर उपलब्ध चुना है, खोज स्टेडियम विस्तृत विचार विमर्श के लिए ckOverflow ...)

अब आप एक Label नियंत्रण XAML में परिभाषित के साथ काम कर सकते हैं, और सिर्फ बटन पर क्लिक इसे करने के लिए कई चेक मार्क आवंटित:

correctButton.Clicked += (sender, e) => 
{ 
    App.DB.IncrementScore(); 
    ScoreLabel.Text = FontAwesome.FACheck.Repeat(App.DB.Score); // replace parameter by whatever method allows you to access the current score number 
}; 
बेशक

, इस दृष्टिकोण कर सकते हैं लेबल की Text विशेषता को सीधे सेट करने के बजाय सार्वजनिक बाइंडेबल string संपत्ति का उपयोग करके एमएमवीएम तरीके का पालन करने के लिए भी अनुकूलित किया जा सकता है, लेकिन इसके लिए मैं आपको सलाह देता हूं कि आप एक शुरुआती एमवीवीएम ट्यूटोरियल को देखें।

+0

धन्यवाद। मैं दृष्टिकोण # 3 का प्रयास कर रहा हूं लेकिन मुझे एक त्रुटि मिल रही है 'स्ट्रिंग को वैध बूलियन के रूप में पहचाना नहीं गया था'। कोई विचार क्यों? –

+0

इस त्रुटि को किस लाइन में फेंक दिया गया है? साथ ही, क्या आप अपनी आवश्यकताओं से मेल खाने के लिए इसे अनुकूलित करने के बाद सटीक बटन क्लिक हैंडलर दिखा सकते हैं? – andreask

+1

क्षमा करें मेरी गलती। मैंने अपने लेबल में 'IsVisible' प्रॉपर्टी जोड़ दी है, जबकि मैं पहले कोड के साथ tinkering था, लेकिन मूल्य खाली छोड़ दिया। मैं आपके समाधान के साथ कोड पर अधिक काम करूंगा, फिर यह बताएगा कि यह कब काम करता है। –

1

यदि स्कोर अधिकतम है तो अधिकतम लेबल जोड़ें और उनकी दृश्यता को बाध्य करें।

या आप लेबल की एक सूचीदृश्य बना सकते हैं और स्रोत को उस संग्रह में जोड़ सकते हैं जब आप आवश्यकतानुसार वृद्धि करते हैं।

+0

मैं यह कर सकता था लेकिन यह एक बहुत साफ समाधान नहीं है क्योंकि मेरे पास अधिकतम 20 अंक हैं। –

+0

मैंने एक और विचार सुझाए जाने के लिए अद्यतन किया। –

0

नोट: मुझे यकीन नहीं है कि यह उत्तर सही है, लेकिन यह एक टिप्पणी के लिए बहुत लंबा है। बस इसका परीक्षण करें और यदि यह काम नहीं करता है तो मैं इस उत्तर को हटा दूंगा


आप प्रोग्रामेटिक रूप से नियंत्रण जोड़ सकते हैं। ध्यान रखें कि आपको अपने मेन थ्रेड पर Label जोड़ने की आवश्यकता है, क्योंकि यह यूआई में बदलाव है। अपने Clicked घटना को यह करें:

correctButton.Clicked += (sender, e) => 
{ 
    App.DB.IncrementScore(); 
    Device.BeginInvokeOnMainThread(() => // On MainThread because it's a change in your UI 
    { 
     Label label = new Label(); 
     label.Text = "{x:Static local:FontAwesome.FACheck}"; // Not sure if this is right syntax... 
     label.FontFamily = "FontAwesome"; 
     label.TextColor = Color.Green; 
     stackPanel.Children.Add(label); 
    }); 
}; 

मामले में आप एक Grid है, तो आप एक Control की SetValue विधि के साथ Grid.Row और Grid.Column सेट कर सकते हैं:

label.SetValue(Grid.RowProperty, 1); 
label.SetValue(Grid.RowProperty, 2); 
1

बस बटन क्लिक ईवेंट में नया लेबल कोड डालें जो आपके स्कोर स्टैक में नए बच्चों को जोड़ देगा।

सीएस पेज कोड: -

button.Clicked += (sender, e) => 
    { 
     App.DB.IncrementScore(); 
     lblStack.Children.Add(new Label {Text = FontAwesome.FACheck, TextColor = Color.Green, FontFamily = "FontAwesome"}); 
    }; 

xamal कोड

<StackLayout Orientation="Horizontal" x:Name="lblStack"/> 

enter image description here

+0

यह उत्तर सरल समाधान दिखता है .. –

संबंधित मुद्दे