मैं c # कोड में DataTemplate कैसे बनाऊं?


82

मैं एक winform इंटरॉप के लिए एक ड्रॉपडाउन सूची बनाने की कोशिश कर रहा हूं, और मैं कोड में ड्रॉपडाउन बना रहा हूं। हालाँकि, मुझे बताई गई डेटाटेम्पलेट के आधार पर डेटा को बाँधने में समस्या आ रही है।

मैं क्या खो रहा हूँ?

drpCreditCardNumberWpf = new ComboBox();  
DataTemplate cardLayout = new DataTemplate {DataType = typeof (CreditCardPayment)};   
StackPanel sp = new StackPanel
{
    Orientation = System.Windows.Controls.Orientation.Vertical
};   

TextBlock cardHolder = new TextBlock {ToolTip = "Card Holder Name"};
cardHolder.SetBinding(TextBlock.TextProperty, "BillToName");
sp.Children.Add(cardHolder);

TextBlock cardNumber = new TextBlock {ToolTip = "Credit Card Number"};
cardNumber.SetBinding(TextBlock.TextProperty, "SafeNumber");
sp.Children.Add(cardNumber);

TextBlock notes = new TextBlock {ToolTip = "Notes"};
notes.SetBinding(TextBlock.TextProperty, "Notes");
sp.Children.Add(notes);

cardLayout.Resources.Add(sp, null);

drpCreditCardNumberWpf.ItemTemplate = cardLayout;

4
कृपया ध्यान दें कि जब ये उत्तर सही थे, तब प्रोग्राम बनाने के लिए वर्तमान अनुशंसित तरीका टेम्पलेट बनाने के लिए XAML को स्ट्रिंग या मेमोरी स्ट्रीम Loadसे XamlReaderकक्षा की विधि का उपयोग करके लोड करना है ।
शेरिदन

जवाबों:


150

यह मानते हुए कि आपने पहले से ही इसके लिए ItemsSourceआदि की स्थापना कर दी है drpCreditCardNumberWpf...

//create the data template
DataTemplate cardLayout = new DataTemplate();
cardLayout.DataType = typeof(CreditCardPayment);

//set up the stack panel
FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(StackPanel));
spFactory.Name = "myComboFactory";
spFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

//set up the card holder textblock
FrameworkElementFactory cardHolder = new FrameworkElementFactory(typeof(TextBlock));
cardHolder.SetBinding(TextBlock.TextProperty, new Binding("BillToName"));
cardHolder.SetValue(TextBlock.ToolTipProperty, "Card Holder Name");
spFactory.AppendChild(cardHolder);

//set up the card number textblock
FrameworkElementFactory cardNumber = new FrameworkElementFactory(typeof(TextBlock));
cardNumber.SetBinding(TextBlock.TextProperty, new Binding("SafeNumber"));
cardNumber.SetValue(TextBlock.ToolTipProperty, "Credit Card Number");
spFactory.AppendChild(cardNumber);

//set up the notes textblock
FrameworkElementFactory notes = new FrameworkElementFactory(typeof(TextBlock));
notes.SetBinding(TextBlock.TextProperty, new Binding("Notes"));
notes.SetValue(TextBlock.ToolTipProperty, "Notes");
spFactory.AppendChild(notes);

//set the visual tree of the data template
cardLayout.VisualTree = spFactory;

//set the item template to be our shiny new data template
drpCreditCardNumberWpf.ItemTemplate = cardLayout;

आप एक ही तरह से मैं निर्धारित किया है उपयोग कर सकते हैं ToolTipपर TextBlockइस तरह के मार्जिन के रूप में सेट अन्य संपत्तियों के लिए है।


1
चांदी की चौखटे में 4 चौखटे की कक्षा नहीं है। मैं xaml.load का भी उपयोग नहीं करना चाहता .. क्या कोई अन्य तरीका है जिसके साथ हम इसे हल कर सकते हैं?
जिज्ञासा



1

पूर्ण संस्करण

var ms = new MemoryStream(Encoding.UTF8.GetBytes(@"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
                                                                 xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""                                                                             
                                                                 xmlns:c=""clr-namespace:MyApp.Converters;assembly=MyApp"">
        <DataTemplate.Resources>
            <c:MyConverter x:Key=""MyConverter""/>
        </DataTemplate.Resources>
        <TextBlock Text=""{Binding ., Converter={StaticResource MyConverter}}""/>
      </DataTemplate>"));
var template = (DataTemplate)XamlReader.Load(ms);

var cb = new ComboBox { };
//Set the data template
cb.ItemTemplate = template;

नोट - XamlReader.Loadईवेंट हैंडलर स्वीकार नहीं करता है।
मिखाइल ओरलोव

-1

खैर, वास्तव में हमारे पास अभी भी एक और तरीका है, अगर आप उन FrameworkElementFactoryचीजों को नापसंद करते हैं, तो आप वास्तव में इसे पसंद करेंगे ।

और मुझे लगता है कि यह सिर्फ प्राकृतिक कोड में मामूली बदलाव करता है, अर्थात्, एक की घोषणा करें UserControlऔर उस पर अपना नियंत्रण रखें, और फिर, FrameworkElementFactoryकॉल करने के लिए सिर्फ एक का उपयोग करें UserControl

सरल डेमो कोड (एफ # में):

let buildView()=StackPanel()
//Build it with natural code
type MyView()=inherit UserControl(Content=buildView())
let factory=FrameworkElementFactory(typeof<MyView>)
let template=DataTemplate(VisualTree=factory)
let list=ItemsControl(ItemsSource=makeData(),ItemTemplate=template)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.