मेरे एप्लिकेशन में एक्सएएमएल और बैकएंड सी # कोड में एक स्विच सेट अप है जो टॉगल ईवेंट का जवाब देता है
<ViewCell x:Name="ss">
<Switch x:Name="ssSwitch" Toggled="SsSwitch" />
</ViewCell>
void SsSwitch(object sender, ToggledEventArgs e) {
// Code to update database here
}
जब पृष्ठ पहली बार लोड होता है तो मैं देखता हूं कि SwSwitch Toggled ईवेंट कहा जाता है।
क्या ऐसा कोई तरीका है जिससे मैं इसे होने से रोक सकता हूं क्योंकि स्टार्टअप पर डेटाबेस को अपडेट करने का कोई कारण नहीं है।
उत्तर:
उत्तर № 1 के लिए 1विकल्प -1: व्यूमोडेल में संपत्ति सेटर का प्रयोग करें
यदि आप एमवीवीएम का उपयोग कर रहे हैं - इसे हल करने का सबसे सरल विकल्प होगा: संपत्ति सेटर का उपयोग करें मूल्य अद्यतन का पता लगाने के लिए (जैसा कि इस पर बताया गया है संपर्क) लेकिन यह विकल्प काम नहीं करता है अगर आप यहां प्रतीक्षित विधियों को कॉल करना चाहते हैं। साथ ही, सर्वोत्तम अभ्यास के रूप में यह अनुशंसा की जाती है कि गुण लागू नहीं होने चाहिए किसी भी समय लेने वाली कार्रवाई.
bool _isToggled;
public bool IsToggled
{
get
{
return _isToggled;
}
set
{
_isToggled = value;
// Add your update code here
}
}
विकल्प -2: उपयोग करें PropertyChanged
ViewModel में घटना
अगला विकल्प होगा सहमत होना PropertyChanged
घटना अपने व्यूमोडेल में और इसे उचित रूप से संभाल लें। यह आपको एसिंक्स हैंडलर्स को परिभाषित करने की अनुमति देता है जो बदले में एसिंक्रोनस विधियों का इंतजार कर सकते हैं।
// Subscribe to event while constructing/assigning viewmodel
// viewCellVM.PropertyChanged += CategoryVM_PropertyChanged;
async void ViewCellVM_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == nameof(ViewCellVM.IsToggled))
{
//call update code here
//await DB.Update();
}
}
विकल्प -3: ओवरराइड OnAppearing()
व्यूसेल में
एक अन्य विकल्प यह सुनिश्चित करना है कि Toggled
ईवेंट हैंडलर के बाद असाइन किया गया है BindingContext
पर अपडेट किया जाता है ViewCell
. इसलिए, मैंने ऑर्डर को ट्रैक करने के लिए एक त्वरित प्रयोग किया Handle_Toggled
, OnBindingContextChanged
, OnAppearing
दृश्य लोड करते समय विधियों को बुलाया जाता है। आदेश निकला:
Handle_Toggled
OnBindingContextChanged
OnAppearing
अत, हैंडलर असाइन करना OnAppearing
विधि (व्यूसेल के कोड-बैक में) को भी इस मामले के लिए काम करना चाहिए:
//XAML:<Switch x:Name="switchBtn" IsToggled="{Binding IsToggled}" />
protected override void OnAppearing()
{
base.OnAppearing();
switchBtn.Toggled += Handle_Toggled;
Debug.WriteLine("OnAppearing");
}
protected override void OnDisappearing()
{
base.OnDisappearing();
switchBtn.Toggled -= Handle_Toggled;
Debug.WriteLine("OnDisappearing");
}
इस तरफ Handle_Toggled
केवल तभी कॉल किया जाएगा जब उपयोगकर्ता स्विच को टॉगल करता है।
उत्तर № 2 के लिए 1
के ऊपर अपने कोड के साथ Switch
पहली शुरुआत में ईवेंट को ट्रिगर नहीं करना चाहिए। यह तभी ट्रिगर होता है जब आपने अपने को बाध्य किया हो IsToggled
आपके व्यूमोडेल के साथ संपत्ति! इसका कारण यह है कि पृष्ठ को पहले प्रारंभ किया जाता है, व्यूमोडेल स्विच को टॉगल करता है और फिर ईवेंट निकाल दिया जाता है।
पहला उपाय यह होगा कि को संभालें IsToggled
संपत्ति और Toggled
घटना दोनों कोड-बैक से (यदि आप अपना कोड mvvm-ing कर रहे हैं तो अनुशंसित नहीं है)। व्यूमोडेल से दोनों को संभालने का बेहतर समाधान होगा।
समस्या यह है, कि Switch
नियंत्रण में कोई नहीं है Command
संपत्ति। a . से आबद्ध होने के लिए आपको एक व्यवहार का उपयोग करना होगा Command.
शारदा गुरुराज ने पहले से ही एक अच्छी व्याख्या के साथ ऊपर एक लिंक पोस्ट किया है।
शारदा गुरुराज स्टैक ओवरफ्लो लिंक का संक्षिप्त समाधान फॉर्म यहां दिया गया है: Xamarin प्रपत्र स्विच टॉगल ईवेंट व्यूमोडेल के साथ बंधता नहीं है
<Switch IsToggled="{Binding IsToggled}">
<Switch.Behaviors>
<behaviors:EventHandlerBehavior EventName="Toggled">
<behaviors:InvokeCommandAction Command="{Binding ToggleSwitchCommand}" />
</behaviors:EventHandlerBehavior>
</Switch.Behaviors>
आगे की जानकारीयां:
- https://blog.xamarin.com/turn-events-into-commands-with-behaviors/
- https://forums.xamarin.com/discussion/64374/switch-with-istoggled-binding-is-throwing-toggled-event-on-init-when-bound-value-is-true