C # 코드에서 DataTemplate을 어떻게 빌드합니까?


82

winform interop에 대한 드롭 다운 목록을 작성하려고하는데 코드에서 드롭 다운을 만들고 있습니다. 그러나 지정한 DataTemplate을 기반으로 바인딩 할 데이터를 가져 오는 데 문제가 있습니다.

내가 무엇을 놓치고 있습니까?

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
이 답변은 당시에는 정확했지만 프로그래밍 방식으로 템플릿을 만드는 현재 권장되는 Load방법은 XamlReader클래스 의 메서드를 사용하여 문자열 또는 메모리 스트림에서 XAML을로드하는 것입니다 .
Sheridan

답변:


150

이미 ItemsSourceetc를 설정했다고 가정하면 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위해 TextBlocks에서 설정 한 것과 동일한 방법을 사용할 수 있습니다 .


1
silverlight 4 frameworkelementfactory 클래스가 없습니다. 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이벤트 핸들러를 허용하지 않습니다.
Mikhail Orlov

-1

글쎄, 우리는 여전히 다른 방법이 있습니다. 당신이 그런 FrameworkElementFactory것들을 싫어한다면 당신은 정말 그것을 좋아할 것입니다.

그리고 난 그냥하는 선언되어 자연 코드를 약간 변경하게 생각 UserControl하고 그리고 그것으로 컨트롤을 놓고, 그냥 하나를 사용 FrameworkElementFactory를 호출 UserControl.

간단한 데모 코드 (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)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.