Làm cách nào để tạo một DataTemplate trong mã c #?


81

Tôi đang cố gắng tạo danh sách thả xuống cho một tương tác biểu mẫu win và tôi đang tạo danh sách thả xuống bằng mã. Tuy nhiên, tôi gặp sự cố khi liên kết dữ liệu dựa trên DataTemplate mà tôi chỉ định.

Tôi đang thiếu gì?

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
Xin lưu ý rằng mặc dù những câu trả lời này đúng vào thời điểm đó, nhưng cách được khuyến nghị hiện tại để tạo mẫu theo chương trình là tải XAML từ một chuỗi hoặc một luồng bộ nhớ bằng cách sử dụng Loadphương thức của XamlReaderlớp.
Sheridan

Câu trả lời:


150

Giả sử rằng bạn đã thiết lập ItemsSourcev.v. cho 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;

Bạn có thể sử dụng cùng một cách mà tôi đã đặt ToolTiptrên TextBlocks để đặt các thuộc tính khác như lề.


1
trong lớp khung đạt chuẩn Silverlight 4 không có ở đó. Tôi cũng không muốn sử dụng xaml.load .. có cách nào khác mà chúng tôi có thể giải quyết nó không?
tò mò

1
Đối với Silverlight 4/5 ... ref .: blogs.msdn.com/b/scmorris/archive/2008/04/14/...
Nordes


1

Phiên bản đầy đủ

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;

Lưu ý - XamlReader.Loadkhông chấp nhận trình xử lý sự kiện.
Mikhail Orlov

-1

À, quả thực chúng ta vẫn còn một cách khác, bạn sẽ rất thích nếu không thích những FrameworkElementFactoryđiều đó.

Và tôi nghĩ rằng nó chỉ thực hiện những thay đổi nhỏ đối với mã tự nhiên, đó là khai báo a UserControlvà đặt quyền kiểm soát của bạn vào nó, sau đó, chỉ sử dụng một FrameworkElementFactoryđể gọi UserControl.

Mã demo đơn giản (trong F #):

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.