दिलचस्प पोस्ट
आईआईएस 7.5+ पुट और रेस्टफ़ुल सेवा के लिए हटाएं, विस्तारहीन आप अपनी प्राथमिक कुंजी कैसे पसंद करते हैं? स्मृति विखंडन क्या है? asp.net का उपयोग करके एम्बेडेड छवि के साथ मेल भेजना XSL में 'कॉल-टेम्पलेट' और 'लागू-टेम्पलेट' के बीच क्या अंतर हैं? याद रखें और फ़ाइल इनपुट को फिर से बदलना एक्सएचटीएमएल स्व-निहित टैग को छोड़कर RegEx मैच खुली टैग एक पॉलीलाइन में एक बिंदु खोजें, जो एक लेटेंग के निकटतम है फ़ॉर्म इनपुट टेक्स्ट फ़ील्ड में अनुमत वर्णों की सीमा सीमा कैसे PHP चर वैल्यू चर चर को असाइन करने के लिए? PHP में, "<<<" क्या दर्शाता है? मैं केवल एक Git रिपॉजिटरी की उपनिर्देशिका कैसे क्लोन करता हूं? पायथन: थ्रेडिंग और मल्टीप्रोसेसिंग मॉड्यूल के बीच अंतर क्या है? कैसे WinForms कोड लिखने के लिए कि प्रणाली फ़ॉन्ट और डीपीआई सेटिंग्स को ऑटो तराजू? कन्वर्ट एचएच: एमएम: एसएस स्ट्रिंग सेकंड में केवल जावास्क्रिप्ट में

NAMED सामग्री के साथ एक WPF UserControl कैसे बनाएँ

मेरे पास अनुबद्ध कमांड और तर्क के साथ नियंत्रण का एक सेट है जो लगातार उसी तरीके से पुन: उपयोग किया जाता है। मैंने एक उपयोगकर्ता नियंत्रण बनाने का निर्णय लिया है जो सभी सामान्य नियंत्रण और तर्क को रखता है।

हालांकि मुझे नियंत्रण की भी आवश्यकता है कि वह सामग्री धारण करने में सक्षम हो जिसे नाम दिया जा सके। मैंने निम्नलिखित की कोशिश की:

<UserControl.ContentTemplate> <DataTemplate> <Button>a reused button</Button> <ContentPresenter Content="{TemplateBinding Content}"/> <Button>a reused button</Button> </DataTemplate> </UserControl.ContentTemplate> 

हालांकि ऐसा लगता है कि उपयोगकर्ता नियंत्रण के अंदर किसी भी सामग्री को रखा नहीं जा सकता। उदाहरण के लिए यदि मैं निम्नलिखित तरीके से नियंत्रण का उपयोग करता हूं:

 <lib:UserControl1> <Button Name="buttonName">content</Button> </lib:UserControl1> 

मुझे निम्न त्रुटि मिली:

तत्व 'बटन पर नाम विशेषता मान' बटन 'सेट नहीं किया जा सकता 'बटन' तत्व '' UserControl1 '' के दायरे के तहत है, जो पहले से एक नाम दर्ज किया गया था, जब इसे किसी दूसरे क्षेत्र में परिभाषित किया गया था।

अगर मैं बटन को हटाता हूं, तो यह संकलित करता है, हालांकि मुझे सामग्री का नाम देने में सक्षम होना चाहिए। इसे कैसे प्राप्त किया जा सकता है?

वेब के समाधान से एकत्रित समाधान "NAMED सामग्री के साथ एक WPF UserControl कैसे बनाएँ"

उत्तर यह करने के लिए एक UserControl का उपयोग नहीं करना है

ContentControl तक फैली हुई एक क्लास बनाएं

 public class MyFunkyControl : ContentControl { public static readonly DependencyProperty HeadingProperty = DependencyProperty.Register("Heading", typeof(string), typeof(HeadingContainer), new PropertyMetadata(HeadingChanged)); private static void HeadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { ((HeadingContainer) d).Heading = e.NewValue as string; } public string Heading { get; set; } } 

फिर सामग्री निर्दिष्ट करने के लिए एक शैली का उपयोग करें

 <Style TargetType="control:MyFunkyControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="control:MyFunkyContainer"> <Grid> <ContentControl Content="{TemplateBinding Content}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> 

और अंत में – इसका उपयोग करें

 <control:MyFunkyControl Heading="Some heading!"> <Label Name="WithAName">Some cool content</Label> </control:MyFunkyControl> 

ऐसा लगता है कि यह संभव नहीं है जब XAML का उपयोग किया जाता है जब मैं वास्तव में सभी नियंत्रणों की ज़रूरत होती है, तो कस्टम नियंत्रण एक उथल-पुल लगते हैं, लेकिन उन्हें थोड़ी सी तर्क के साथ एक साथ समूह की जरूरत होती है और नामित सामग्री की अनुमति देती है।

जेडी के ब्लॉग पर मॅकेंइर के समाधान का समाधान बताता है, सबसे अच्छा समझौता होने लगता है XAML में अभी भी परिभाषित होने की अनुमति देने के लिए जेडी के समाधान को बढ़ाने का एक तरीका निम्नानुसार हो सकता है:

  protected override void OnInitialized(EventArgs e) { base.OnInitialized(e); var grid = new Grid(); var content = new ContentPresenter { Content = Content }; var userControl = new UserControlDefinedInXAML(); userControl.aStackPanel.Children.Add(content); grid.Children.Add(userControl); Content = grid; } 

ऊपर मेरे उदाहरण में मैंने UserControlDefinedInXAML नामक एक यूजर कंट्रोल बनाया है जो कि XAML का उपयोग कर किसी भी सामान्य उपयोगकर्ता नियंत्रण की तरह परिभाषित करता है। मेरे UserControlDefinedInXAML में मेरे पास एक StackPanel नामक स्टैक पैनल है, जिसके भीतर मैं अपनी नामांकित सामग्री को प्रकट करना चाहता हूं।

मैंने एक अन्य विकल्प का इस्तेमाल किया है जिसे Loaded ईवेंट में केवल Name संपत्ति सेट करना है

मेरे मामले में, मेरे पास एक जटिल नियंत्रण था, जिसे मैं कोड-पीछे में नहीं बनाना चाहता था, और यह किसी विशेष व्यवहार के लिए एक विशिष्ट नाम के साथ एक वैकल्पिक नियंत्रण की तलाश करता था, और जब से मुझे पता चला कि मैं नाम बदल सकता हूं DataTemplate मुझे लगा कि मैं इसे Loaded ईवेंट में भी कर सकता हूं।

 private void Button_Loaded(object sender, RoutedEventArgs e) { Button b = sender as Button; b.Name = "buttonName"; } 

कभी-कभी आपको तत्व को सी # से संदर्भित करने की आवश्यकता हो सकती है उपयोग के मामले पर निर्भर करते हुए, आप x:Uid बजाय x:Uid सेट कर सकते हैं x:Name और एक यूआईडी खोजक विधि को कॉल करके तत्वों तक पहुंचें जैसे कि यूआईएफ द्वारा अपने यूआईडी द्वारा ऑब्जेक्ट प्राप्त करें ।

मैंने प्रत्येक तत्व को प्राप्त करने के लिए अतिरिक्त संपत्ति बनाने के लिए चुना है:

  public FrameworkElement First { get { if (Controls.Count > 0) { return Controls[0]; } return null; } } 

यह मुझे XAML में बाल तत्वों तक पहुंचने में सक्षम बनाता है:

 <TextBlock Text="{Binding First.SelectedItem, ElementName=Taxcode}"/> 

आप उपयोगकर्ता नियंत्रण में सेट नाम के लिए इस सहायक का उपयोग कर सकते हैं:

 using System; using System.Reflection; using System.Windows; using System.Windows.Media; namespace UI.Helpers { public class UserControlNameHelper { public static string GetName(DependencyObject d) { return (string)d.GetValue(UserControlNameHelper.NameProperty); } public static void SetName(DependencyObject d, string val) { d.SetValue(UserControlNameHelper.NameProperty, val); } public static readonly DependencyProperty NameProperty = DependencyProperty.RegisterAttached("Name", typeof(string), typeof(UserControlNameHelper), new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.None, (d, e) => { if (!string.IsNullOrEmpty((string)e.NewValue)) { string[] names = e.NewValue.ToString().Split(new char[] { ',' }); if (d is FrameworkElement) { ((FrameworkElement)d).Name = names[0]; Type t = Type.GetType(names[1]); if (t == null) return; var parent = FindVisualParent(d, t); if (parent == null) return; var p = parent.GetType().GetProperty(names[0], BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty); p.SetValue(parent, d, null); } } })); public static DependencyObject FindVisualParent(DependencyObject child, Type t) { // get parent item DependencyObject parentObject = VisualTreeHelper.GetParent(child); // we've reached the end of the tree if (parentObject == null) { var p = ((FrameworkElement)child).Parent; if (p == null) return null; parentObject = p; } // check if the parent matches the type we're looking for DependencyObject parent = parentObject.GetType() == t ? parentObject : null; if (parent != null) { return parent; } else { // use recursion to proceed with next level return FindVisualParent(parentObject, t); } } } } 

और आपकी विंडो या नियंत्रण कोड के पीछे आप सम्पत्ति द्वारा नियंत्रण सेट करते हैं:

  public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } public Button BtnOK { get; set; } } 

आपकी विंडो xaml:

  <Window x:Class="user_Control_Name.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:test="clr-namespace:user_Control_Name" xmlns:helper="clr-namespace:UI.Helpers" x:Name="mainWindow" Title="MainWindow" Height="350" Width="525"> <Grid> <test:TestUserControl> <Button helper:UserControlNameHelper.Name="BtnOK,user_Control_Name.MainWindow"/> </test:TestUserControl> <TextBlock Text="{Binding ElementName=mainWindow,Path=BtnOK.Name}"/> </Grid> </Window> 

UserControlNameHelper सेट कंट्रोल टू प्रॉपर्टी के लिए अपना नियंत्रण नाम और अपना क्लास नाम प्राप्त करें

 <Popup> <TextBox Loaded="BlahTextBox_Loaded" /> </Popup> 

कोड के पीछे:

 public TextBox BlahTextBox { get; set; } private void BlahTextBox_Loaded(object sender, RoutedEventArgs e) { BlahTextBox = sender as TextBox; } 

वास्तविक समाधान माइक्रोसॉफ्ट के लिए इस मुद्दे को ठीक करने के लिए होगा, साथ ही अन्य सभी टूटे हुए दृश्य पेड़ों के साथ। Hypothetically बोल रहा है

फिर भी एक और हल: संदर्भ के रूप में रिलेटिवसार्स तत्व।

नामित नियंत्रणों का एक समूह बनाते समय मेरे पास टैबक्रॉंटोल का उपयोग करते हुए एक ही समस्या थी

मेरा समाधान एक नियंत्रण टेम्पलेट का उपयोग करना था जिसमें एक टैब पृष्ठ में दिखाए जाने के लिए मेरे सारे नियंत्रण होते हैं। टेम्पलेट के अंदर आप नाम गुण का उपयोग कर सकते हैं और कम से कम एक ही टेम्पलेट के भीतर अन्य नियंत्रणों से नामित नियंत्रण के गुणों को भी डेटा बाँध सकते हैं।

TabItem नियंत्रण की सामग्री के रूप में, एक सरल नियंत्रण का उपयोग करें और तदनुसार ControlTemplate सेट करें:

 <Control Template="{StaticResource MyControlTemplate}"/> 

उन नामों को नियंत्रित करने के लिए, जो कि आपके पीछे दिए गए कोड से टेम्पलेट के अंदर पहुंच रहे हैं, आपको विज़ुअल ट्री का उपयोग करना होगा।