Próbuję zbudować listę rozwijaną dla współdziałania winform i tworzę listę rozwijaną w kodzie. Jednak mam problem z uzyskaniem danych do powiązania w oparciu o określony przeze mnie DataTemplate.
czego mi brakuje?
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;
c#
wpf
datatemplate
Saman Hakimzadeh Abyaneh
źródło
źródło
Load
metodyXamlReader
klasy.Odpowiedzi:
Zakładając, że już skonfigurowałeś
ItemsSource
itp. DladrpCreditCardNumberWpf
...//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;
Możesz użyć tego samego sposobu, w jaki ustawiłem
ToolTip
naTextBlock
s, aby ustawić inne właściwości, takie jak marginesy.źródło
Pełna wersja
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;
źródło
XamlReader.Load
nie akceptuje programów obsługi zdarzeń.Cóż, rzeczywiście, wciąż mamy inny sposób, naprawdę ci się spodoba, jeśli nie lubisz tych
FrameworkElementFactory
rzeczy.Myślę, że po prostu wprowadza drobne zmiany w kodzie naturalnym, to znaczy deklaruje a
UserControl
i umieszcza w nim kontrolę, a następnie użyj tylko jednego,FrameworkElementFactory
aby wywołaćUserControl
.Prosty kod demonstracyjny (w 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)
źródło