wpf 在后面创建数据模板代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14053804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:47:28  来源:igfitidea点击:

create datatemplate code behind

c#wpfc#-4.0

提问by Love_Egypt

I am trying to create a ListBox view for show data, and I want it to contain a ListBox with a datatemplate for 2 columns "Product ID & Product Barcode"

我正在尝试为显示数据创建一个 ListBox 视图,我希望它包含一个 ListBox,其中包含一个数据模板,用于 2 列“产品 ID 和产品条形码”

I want to create it either using pure C# code or if possible load it through xaml? If I can create a template I can get in c# as a resource of sorts.

我想使用纯 C# 代码创建它,或者如果可能的话通过 xaml 加载它?如果我可以创建一个模板,我就可以将 c# 作为各种资源。

What I have made until now is: In XAML :

到目前为止,我所做的是:在 XAML 中:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="37*" />
        <RowDefinition Height="88*" />
    </Grid.RowDefinitions>
    <TextBlock Text="Type Your Search :" HorizontalAlignment="Left"  VerticalAlignment="Bottom" Width="112" Height="15.96" Margin="20,0,0,4" />

    <TextBox HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="25" Width="300" Margin="0,0,44,0" x:Name="txtCAuto" TextWrapping="NoWrap" HorizontalContentAlignment="Right" />

    <ListBox x:Name="lbSuggestion" SelectionChanged="lbSuggestion_SelectionChanged" Foreground="Black" Width="300" Margin="0,0,44,0"  FlowDirection="RightToLeft" Background="LightYellow" Grid.Row="1" Visibility="Collapsed"  ScrollViewer.HorizontalScrollBarVisibility="Auto" ItemsSource="{Binding}"  HorizontalAlignment="Right" VerticalAlignment="Top" HorizontalContentAlignment="Right" BorderBrush="Transparent"  Grid.IsSharedSizeScope="True">
    </ListBox>
</Grid>

In Code Behind:

在后面的代码中:

string typedString = txtCAuto.Text.ToUpper();
        List<string> autoList = new List<string>();
        autoList.Clear();

         prodDetails ps = SelProd4Sale();

        foreach (string item in ps.ProdBrcdList)
        {
            if (!string.IsNullOrEmpty(txtCAuto.Text))
            {
                if (item.StartsWith(typedString))
                {
                    //autoList.Add(item);
                    FrameworkElementFactory colProdID = new FrameworkElementFactory(typeof(TextBlock));
                    Binding prodID = new Binding(ps.ProdIDList.ToString());
                    colProdID.SetBinding(TextBlock.TextProperty, prodID);

                    FrameworkElementFactory colProdBarcode = new FrameworkElementFactory(typeof(TextBlock));
                    Binding prodBarcode = new Binding();
                    prodBarcode.Path = new PropertyPath(ps.ProdBrcdList.ToString());
                    colProdBarcode.SetBinding(TextBlock.TextProperty, prodBarcode);


                    FrameworkElementFactory sb = new FrameworkElementFactory(typeof(StackPanel));
                    sb.AppendChild(colProdID);
                    sb.AppendChild(colProdBarcode);

                    dTemplate = new DataTemplate { VisualTree = sb };
                    dTemplate.Seal();


                }
            }
        }

        if (autoList.Count > 0)
        {
            lbSuggestion.ItemTemplate = dTemplate;
            //lbSuggestion.ItemsSource = autoList;
            lbSuggestion.Visibility = Visibility.Visible;
        }
        else if (txtCAuto.Text.Equals(""))
        {
            lbSuggestion.Visibility = Visibility.Collapsed;
            lbSuggestion.ItemsSource = null;
        }
        else
        {
            lbSuggestion.Visibility = Visibility.Collapsed;
            lbSuggestion.ItemsSource = null;
        }

but there is no data appears, any suggestion please. thanks,

但是没有数据出现,请提出任何建议。谢谢,

回答by Sisyphe

You can define resources in xaml and retrieve it in code behind if it has an x:Keydefined.

您可以在 xaml 中定义资源并在后面的代码中检索它(如果它已x:Key定义)。

In your xaml :

在您的 xaml 中:

<DataTemplate x:Key="anyId">...</DataTemplate>

And in your code behind :

在你后面的代码中:

var dataTemplate = Application.Current.TryFindResource("anyId") as DataTemplate;

or

或者

var dataTemplate = Application.Current.FindResource("anyId") as DataTemplate;

回答by Mats Magnem

I have created DataTemplate like this:

我已经创建了这样的 DataTemplate:

private DataTemplate getDataTemplate()
{
    DataTemplate retVal = null;
    String markup = String.Empty;

    markup = "<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:local=\"clr-namespace:YOUR.PROJECT.NAMESPACE;assembly=YOUR.PROJECT.NAMESPACE\">";
    markup += "<Grid>";
    markup += "<TextBlock Text=\"{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content, Mode=OneWay}\" />";
    markup += "</Grid>";
    markup += "</DataTemplate>";

    retVal = (DataTemplate)XamlReader.Load(markup);

    return retVal;
}

...and then call this method where you need it (like OnApplyTemplate)

...然后在需要的地方调用此方法(如 OnApplyTemplate)

this.ContentTemplate = getDataTemplate();

NOTE : You may have to change the "xmlns" for WPF, because this example is taken from one of my Silverlight projects. But the idea is the same.

注意:您可能必须更改 WPF 的“xmlns”,因为此示例取自我的 Silverlight 项目之一。但想法是一样的。

回答by Mark Jones

Conditional XAML DataTemplate

条件 XAML 数据模板

Defining a static DataTemplate in your object's XAML file is the customary way to approach this. Also, the example Microsoft provides for DataTemplate.LoadContent() is nifty for showing how to switch templates dynamically at run-time (see DataTemplate.LoadContent method) when needed.

在对象的 XAML 文件中定义静态 DataTemplate 是解决此问题的惯用方法。此外,Microsoft 为 DataTemplate.LoadContent() 提供的示例非常适合展示如何在需要时在运行时动态切换模板(请参阅DataTemplate.LoadContent 方法)。

However, if you have a special requirement of conditional XAML compilation (like omitting debug-only XAML when you're building a Release version), you will need to resort to the XamlReader.Load() approach (see XamlReader.Load method).

但是,如果您有条件 XAML 编译的特殊要求(例如在构建发布版本时省略仅调试 XAML),您将需要求助于 XamlReader.Load() 方法(请参阅XamlReader.Load 方法)。

To that end, I thought a bit more detailed example might be helpful. Here, I have a debug-only ListView that is bound to an ObservableCollection<> of custom objects. The ListView is not defined in static XAML, since it's needed only in Debug mode ...

为此,我认为更详细的示例可能会有所帮助。在这里,我有一个仅限调试的 ListView,它绑定到一个 ObservableCollection<> 的自定义对象。ListView 不是在静态 XAML 中定义的,因为它只在调试模式下需要......



Custom class:

自定义类:

    class ActiveNotification
    {
        public String Name { get; set; }
        public String Type { get; set; }
        public String DayOfWeek { get; set; }
        public DateTime DeliveryTime { get; set; }
        public String Id { get; set; }
    }

Private member variables:

私有成员变量:

    readonly ObservableCollection<ActiveNotification> _activeNotifications = new ObservableCollection<ActiveNotification>();
    readonly ListView listViewNotifications = 
        new ListView 
        { 
            Visibility = Visibility.Collapsed,
            HorizontalAlignment = HorizontalAlignment.Left,
            VerticalAlignment = VerticalAlignment.Bottom,
        };

Load-time ListView setup:

加载时 ListView 设置:

        // Set up notifications list
        listViewNotifications.SetBinding(ListView.ItemsSourceProperty, new Binding { Source = _activeNotifications });
        listViewNotifications.Tapped += listViewNotifications_Tapped;
        Grid.SetRowSpan(listViewNotifications, 2);
        Grid.SetColumnSpan(listViewNotifications, 2);
        var xamlString =
            "<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\">" +
                "<StackPanel Orientation=\"Horizontal\" VerticalAlignment=\"Center\">" +
                    "<TextBlock Text=\"{Binding Name}\" Margin=\"20,0,10,0\"/>" +
                    "<TextBlock Text=\"{Binding Type}\" Margin=\"0,0,10,0\"/>" +
                    "<TextBlock Text=\"{Binding DayOfWeek}\" Margin=\"0,0,10,0\"/>" +
                    "<TextBlock Text=\"{Binding DeliveryTime}\" Margin=\"0,0,10,0\"/>" +
                    "<TextBlock Text=\"{Binding Id}\"/>" +
                "</StackPanel>" +
            "</DataTemplate>";
        var dataTemplate = (DataTemplate)XamlReader.Load(xamlString);
        listViewNotifications.ItemTemplate = dataTemplate;
        GridMain.Children.Add(listViewNotifications);