本文介绍了查找文本框在一个DataTemplate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在有一个DataTemplate一些内容,我需要在后面的事件处理程序中的code访问。
下面的工作,如果按钮和文本框具有相同的父。
我将如何处理更复杂的布局?
如果在一个DataTemplate访问一个元素的一般方法是什么?

 < D​​ataTemplate中X:关键=fieldDateTemplate>
    < StackPanel的>
        < D​​atePicker的SelectedDate ={绑定路径= fieldValue方法}/>
        <文本框X:名称=tbFindMe文本=findME/>
        <按钮内容=FindTB点击=FindTB_clickWIDTH =60的Horizo​​ntalAlignment =左/>
    < / StackPanel的>
< / DataTemplate中>

私人无效FindTB_click(对象发件人,RoutedEventArgs E)
{
    按钮BTN =(按钮)发送;
    文本框TB =((StackPanel中)btn.Parent).FindName(tbFindMe)的文本框;
}
 

谢谢..

不得不作出更新由dkozl
提供的出色答卷如果有一个列表框或ListView模板中,因为它会停在那里,它是失败
这是现在正在为修复

 私人的DataTemplate FieldTemplateDetail2(对象发件人,从内容presenter CP)
{
    CP =无效;
    如果(发件人== NULL)返回NULL;
    变种D =发件人为DependencyObject的;
    DependencyObject的dNext = NULL;
    DataTemplate中的模板= NULL;
    而(D!= NULL)
    {
        如果(d为内容presenter)
        {
            的Debug.WriteLine(FieldTemplateDetail2 d为内容presenter+ d.ToString());
            CP = D的内容presenter;
        }

        dNext = VisualTreeHelper.GetParent(D);
        如果(dNext = NULL和放大器;!&安培; dNext是一个ListBoxItem)
        {
            的Debug.WriteLine(FieldTemplateDetail2 dNext是ListBoxItem的+ d.ToString());
            如果(CP!= NULL)
            {
                的Debug.WriteLine(FieldTemplateDetail2 CP =空!+ cp.ToString());
                CP = cp.ContentTemplate.FindName(fieldTemplateDetail,CP)的内容presenter;
                如果(CP!= NULL)
                {
                    的Debug.WriteLine(FieldTemplateDetail2 CP fieldTemplateDetail!= NULL+ cp.ToString());
                    模板= cp.ContentTemplate;
                    如果(模板== NULL和放大器;&安培;!cp.ContentTemplateSelector = NULL)
                        模板= cp.ContentTemplateSelector.SelectTemplate(cp.Content,CP);
                    打破;
                }
                CP =无效;
            }
        }
        // D = VisualTreeHelper.GetParent(D);
        D = dNext;
    }
    返回模板;
}
 

基于以下这一切,code

似乎是基于答案修复从dkozl
随着安葬在网格中Expandar结核病它比上面的简单示例

更困难

 变种D =发件人为DependencyObject的;
内容presenter CP = NULL;
而(D = NULL和放大器;!&安培;!(d为一个ListBoxItem))
{
    如果(d为内容presenter)CP = D的内容presenter;
    D = VisualTreeHelper.GetParent(四);
}
如果(CP!= NULL)CP = cp.ContentTemplate.FindName(fieldTemplateDetail,CP)的内容presenter;
如果(CP!= NULL)
{
    VAR模板= cp.ContentTemplate;
    如果(模板== NULL和放大器;&安培;!cp.ContentTemplateSelector = NULL)
        模板= cp.ContentTemplateSelector.SelectTemplate(cp.Content,CP);
    如果(模板!= NULL)
    {
        VAR TB = template.FindName(tbFindMe,CP)的文本框;
        如果(TB ==空)的MessageBox.show(空,ContentTemplateSelector);
        其他的MessageBox.show(tb.TextContentTemplateSelector);
    }
}
 

根据要求所有code

 <窗​​口x:类=ListViewTemplateSelectorWPF.MainWindow
        的xmlns =htt​​p://schemas.microsoft.com/winfx/2006/xaml/$p$psentation
        的xmlns:X =htt​​p://schemas.microsoft.com/winfx/2006/xaml
        XMLNS:地方=CLR的命名空间:ListViewTemplateSelectorWPF
        的DataContext ={绑定的RelativeSource = {的RelativeSource自我}}
        标题=主窗口高度=350宽度=525>
    < Window.Resources>
        < BooleanToVisibilityConverter X:关键=BVC/>
        <地方:FieldTemplateSelector X:关键=fieldTemplateSelector/>
        < D​​ataTemplate中X:关键=windowTemplate>
            <文本框X:名称=windowTemplateTB文本=windowTemplate/>
        < / DataTemplate中>
    < /Window.Resources>
    <电网>
        < Grid.RowDefinitions>
            < RowDefinition身高=*/>
            < RowDefinition高度=自动/>
        < /Grid.RowDefinitions>
        &所述;列表框Grid.Row =0×:名称=lbFields
                 的ItemsSource ={绑定路径=字段}
                 Horizo​​ntalContentAlignment =拉伸>
            < ListBox.Resources>
                < D​​ataTemplate中X:关键=fieldStringTemplate>
                    < StackPanel的X:名称=fieldString能见度=可见>
                        <文本框文本={绑定路径= fieldValue方法}/>
                    < / StackPanel的>
                < / DataTemplate中>
                < D​​ataTemplate中X:关键=fieldDateTemplate>
                    <电网>
                        < Grid.RowDefinitions>
                            < RowDefinition高度=自动/>
                            < RowDefinition高度=自动/>
                            < RowDefinition高度=自动/>
                        < /Grid.RowDefinitions>
                        < D​​atePicker的Grid.Row =0SelectedDate ={绑定路径= fieldValue方法}/>
                        !&其中;  - &所述;文本框Grid.Row =1×:名称=tbFindMe文本=findME/>
                        <按钮Grid.Row =2CONTENT =FindTB点击=FindTB_clickWIDTH =60的Horizo​​ntalAlignment =左/>  - >
                        <扩展Grid.Row =1标题=查找>
                            <电网>
                                < Grid.RowDefinitions>
                                    < RowDefinition高度=自动/>
                                    < RowDefinition高度=自动/>
                                < /Grid.RowDefinitions>
                                &所述;文本框Grid.Row =0×:名称=tbFindMe文本=findME/>
                                <按钮Grid.Row =1CONTENT =FindTB点击=FindTB_clickWIDTH =60的Horizo​​ntalAlignment =左/>
                            < /网格>
                        < /扩展>
                    < /网格>
                < / DataTemplate中>
            < /ListBox.Resources>
            < ListBox.ItemTemplate>
                < D​​ataTemplate中数据类型=本地:字段>
                    <电网>
                        < Grid.RowDefinitions>
                            < RowDefinition高度=自动/>
                            < RowDefinition高度=自动/>
                        < /Grid.RowDefinitions>
                        < Grid.ColumnDefinitions>
                            < ColumnDefinition WIDTH =60/>
                            &所述; ColumnDefinition宽度=*/>
                        < /Grid.ColumnDefinitions>
                        < TextBlock的Grid.Row =0Grid.Column =0文本={绑定路径=名}/>
                        &所述; TextBlock的Grid.Row =0Grid.Column =1文本={结合路径= DisplayValue}/>
                        &所述;内容presenter Grid.Row =1Grid.Column =0Grid.ColumnSpan =2
                                    能见度={绑定的RelativeSource = {的RelativeSource AncestorType = ListBoxItem的},
                                                         路径= IsSelected,转换器= {的StaticResource BVC}}
                                    X:名称=fieldTemplateDetail
                                    内容={结合}
                                    ContentTemplateSelector ={的StaticResource fieldTemplateSelector}/>
                    < /网格>
                < / DataTemplate中>
            < /ListBox.ItemTemplate>
        < /列表框>
        <按钮Grid.Row =1X:名称=findButtonCONTENT =废按钮WIDTH =100的Horizo​​ntalAlignment =左点击=click_Unselect/>
    < /网格>
< /窗>

使用System.ComponentModel;
命名空间ListViewTemplateSelectorWPF
{
    ///<总结>
    ///为MainWindow.xaml交互逻辑
    ///< /总结>
    ///

    公共部分类主窗口:窗口
    {
        私人列表<现场>田=新的名单,其中,现场>();
        公共主窗口()
        {
            fields.Add(新FieldString(字符串1));
            fields.Add(新FieldString(String2的));
            fields.Add(新FieldDate(日期1));
            fields.Add(新FieldDate(日期2));

            的InitializeComponent();
        }
        公共领域CurField {获得;组; }
        公开名单<现场>字段{{返回领域; }}

        私人无效click_Unselect(对象发件人,RoutedEventArgs E)
        {
            尝试
            {
                按钮TB = this.FindName(findButton)的按钮;
                如果(TB == NULL)的MessageBox.show(空);
                其他的MessageBox.show(tb.Name);
            }
            赶上(例外前)
            {
                的MessageBox.show(Ex.Message,异常findButton);
            }
            尝试
            {
                DataTemplate中DT = this.FindResource(fieldDateTemplate)作为DataTemplate中;
                如果(DT == NULL)的MessageBox.show(DT找不到);
                其他的MessageBox.show(DT找到);
            }
            赶上(例外前)
            {
                的MessageBox.show(Ex.Message,异常DT);
            }

            lbFields.SelectedIndex = -1;
        }

        私人无效FindTB_click(对象发件人,RoutedEventArgs E)
        {
            变种D =发件人为DependencyObject的;
            而(D =空&安培;!&安培;!(d为内容presenter))D = VisualTreeHelper.GetParent(四);
            变种CP = D的内容presenter;
            如果(CP!= NULL)
            {
                VAR模板= cp.ContentTemplate;
                如果(模板== NULL和放大器;&安培;!cp.ContentTemplateSelector = NULL)
                    模板= cp.ContentTemplateSelector.SelectTemplate(cp.Content,CP);
                如果(模板!= NULL)
                {
                    VAR TB = template.FindName(tbFindMe,CP)的文本框;
                    的MessageBox.show(tb.TextContentTemplateSelector);
                }
            }

            按钮BTN =(按钮)发送;
            //MessageBox.Show("button NAME =+ btn.Name);
            尝试
            {
                文本框TB =((网格)btn.Parent).FindName(tbFindMe)的文本框;
                如果(TB == NULL)的MessageBox.show(空,手册);
                其他的MessageBox.show(tb.Text,手册);
            }
            赶上(例外前)
            {
                的MessageBox.show(Ex.Message,异常手册);
            }
        }
    }
    公共抽象类领域:INotifyPropertyChanged的
    {
        公共事件PropertyChangedEventHandler的PropertyChanged;
        保护无效NotifyPropertyChanged(字符串信息)
        {
            如果(的PropertyChanged!= NULL)
            {
                的PropertyChanged(这一点,新PropertyChangedEventArgs(信息));
            }
        }
        私人字符串名称;
        公共字符串名称{{返回名称; }}
        公共抽象的字符串DisplayValue {获得; }
        公共字段(字符串名称){名称=名称; }
    }
    公共类FieldString:现场
    {
        私人字符串fieldValue方法;
        公共字符串fieldValue方法
        {
            {返回fieldValue方法; }
            组
            {
                如果(fieldValue方法==值)回报;
                fieldValue方法=价值;
                NotifyPropertyChanged(fieldValue方法);
                NotifyPropertyChanged(DisplayValue);
            }
        }
        公众覆盖字符串DisplayValue
        {
            {返回fieldValue方法; }
        }
        公共FieldString(字符串名称):基地(名称){}
        公共FieldString(字符串名称,字符串fieldValue方法):基地(名称)
        {fieldValue方法= fieldValue方法; }
    }
    公共类FieldDate:现场
    {
        私营的DateTime? fieldValue方法= NULL;
        公开日期时间? fieldValue方法
        {
            {返回fieldValue方法; }
            组
            {
                如果(fieldValue方法==值)回报;
                fieldValue方法=价值;
                NotifyPropertyChanged(fieldValue方法);
                NotifyPropertyChanged(DisplayValue);
            }
        }
        公众覆盖字符串DisplayValue
        {
            {返回FieldValue.ToString(); }
        }
        公共FieldDate(字符串名称)
            :基地(名称){}
        公共FieldDate(字符串名称,日期时间fieldValue方法)
            :基地(名称)
        {fieldValue方法= fieldValue方法; }
    }
    公共类FieldTemplateSelector:DataTemplateSelector
    {
        公众覆盖的DataTemplate
            SelectTemplate(对象项目,DependencyObject的容器)
        {
            FrameworkElement的元素=容器FrameworkElement的;
            如果(项目= NULL和放大器;!&安培;产品领域)
            {
                System.Diagnostics.Debug.WriteLine(田);
                如果(产品FieldString)
                {
                    System.Diagnostics.Debug.WriteLine(FieldString);
                    返回element.FindResource(fieldStringTemplate),为的DataTemplate;
                }
                如果(产品FieldDate)
                {
                    System.Diagnostics.Debug.WriteLine(FieldDate);
                    返回element.FindResource(fieldDateTemplate),为的DataTemplate; }

                返回element.FindResource(fieldTemplate),为的DataTemplate;
            }
            其他
                返回element.FindResource(fieldTemplate),为的DataTemplate;
        }
    }
}
 

解决方案

要查找名称的控件放在的DataTemplate ,你需要找到内容presenter 使用该模板,并调用 FindName 该模板与发现内容presenter

 私人无效Button_Click(对象发件人,RoutedEventArgs E)
{
   变种D =发件人为DependencyObject的;
   内容presenter CP = NULL;
   而(D = NULL和放大器;!&安培;!(d为一个ListBoxItem))
   {
       如果(d为内容presenter)CP = D的内容presenter;
       D = VisualTreeHelper.GetParent(四);
   }
   如果(CP!= NULL)
   {
      CP = cp.ContentTemplate.FindName(fieldTemplateDetail,CP)的内容presenter;
      如果(CP!= NULL)
      {
         VAR模板= cp.ContentTemplate;
         如果(模板== NULL和放大器;&安培;!cp.ContentTemplateSelector = NULL)
            模板= cp.ContentTemplateSelector.SelectTemplate(cp.Content,CP);
         如果(模板!= NULL)
         {
            VAR TB = template.FindName(tbFindMe,CP)的文本框;
         }
      }
   }
}
 

Have some elements in a DataTemplate that I need to access in a code behind event handler.
Below works if the button and the textbox have the same Parent.
How would I handle a more complex layout?
If there a general way for accessing an element in a DataTemplate?

<DataTemplate x:Key="fieldDateTemplate">
    <StackPanel>
        <DatePicker SelectedDate="{Binding Path=FieldValue}" />
        <TextBox x:Name="tbFindMe" Text="findME"/>
        <Button Content="FindTB" Click="FindTB_click" Width="60" HorizontalAlignment="Left"/>
    </StackPanel>
</DataTemplate>

private void FindTB_click(object sender, RoutedEventArgs e)
{
    Button btn = (Button)sender;
    TextBox tb = ((StackPanel)btn.Parent).FindName("tbFindMe") as TextBox;
}

Thanks..

Had to make an update to the excellent answer provided by dkozl
It was failing if there was a ListBox or ListView in the template as it would stop there
This is the fix that is working for now

private DataTemplate FieldTemplateDetail2(object sender, out ContentPresenter cp)
{
    cp = null;
    if (sender == null) return null;
    var d = sender as DependencyObject;
    DependencyObject dNext = null;
    DataTemplate template = null;
    while (d != null)
    {
        if (d is ContentPresenter)
        {
            Debug.WriteLine("FieldTemplateDetail2 d is ContentPresenter" + d.ToString());
            cp = d as ContentPresenter;
        }

        dNext = VisualTreeHelper.GetParent(d);
        if (dNext != null &&  dNext is ListBoxItem)
        {
            Debug.WriteLine("FieldTemplateDetail2 dNext is ListBoxItem " + d.ToString());
            if (cp != null)
            {
                Debug.WriteLine("FieldTemplateDetail2 cp != null" + cp.ToString());
                cp = cp.ContentTemplate.FindName("fieldTemplateDetail", cp) as ContentPresenter;
                if (cp != null)
                {
                    Debug.WriteLine("FieldTemplateDetail2 cp fieldTemplateDetail != null" + cp.ToString());
                    template = cp.ContentTemplate;
                    if (template == null && cp.ContentTemplateSelector != null)
                        template = cp.ContentTemplateSelector.SelectTemplate(cp.Content, cp);
                    break;
                }
                cp = null;
            }
        }
        //d = VisualTreeHelper.GetParent(d);
        d = dNext;
    }
    return template;
}

Based on All code below this appears to be a fix based on answer from dkozl
With the tb burried in a Grid in an Expandar it was more difficult than the simple example above

var d = sender as DependencyObject;
ContentPresenter cp = null;
while (d != null && !(d is ListBoxItem))
{
    if (d is ContentPresenter) cp = d as ContentPresenter;
    d = VisualTreeHelper.GetParent(d);
}
if (cp != null) cp = cp.ContentTemplate.FindName("fieldTemplateDetail", cp) as ContentPresenter;
if (cp != null)
{
    var template = cp.ContentTemplate;
    if (template == null && cp.ContentTemplateSelector != null)
        template = cp.ContentTemplateSelector.SelectTemplate(cp.Content, cp);
    if (template != null)
    {
        var tb = template.FindName("tbFindMe", cp) as TextBox;
        if (tb == null) MessageBox.Show("null", "ContentTemplateSelector");
        else  MessageBox.Show(tb.Text, "ContentTemplateSelector");
    }
}

All code as requested

<Window x:Class="ListViewTemplateSelectorWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ListViewTemplateSelectorWPF"
        DataContext="{Binding RelativeSource={RelativeSource self}}"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="bvc" />
        <local:FieldTemplateSelector x:Key="fieldTemplateSelector"/>
        <DataTemplate x:Key="windowTemplate">
            <TextBox x:Name="windowTemplateTB" Text="windowTemplate" />
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0" x:Name="lbFields"
                 ItemsSource="{Binding Path=Fields}"
                 HorizontalContentAlignment="Stretch">
            <ListBox.Resources>
                <DataTemplate x:Key="fieldStringTemplate">
                    <StackPanel x:Name="fieldString" Visibility="Visible">
                        <TextBox Text="{Binding Path=FieldValue}" />
                    </StackPanel>
                </DataTemplate>
                <DataTemplate x:Key="fieldDateTemplate">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="auto"/>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <DatePicker Grid.Row="0" SelectedDate="{Binding Path=FieldValue}" />
                        <!--<TextBox Grid.Row="1" x:Name="tbFindMe" Text="findME"/>
                        <Button Grid.Row="2" Content="FindTB" Click="FindTB_click" Width="60" HorizontalAlignment="Left"/>-->
                        <Expander Grid.Row="1" Header="Find">
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="auto"/>
                                    <RowDefinition Height="Auto"/>
                                </Grid.RowDefinitions>
                                <TextBox Grid.Row="0" x:Name="tbFindMe" Text="findME"/>
                                <Button Grid.Row="1" Content="FindTB" Click="FindTB_click" Width="60" HorizontalAlignment="Left"/>
                            </Grid>
                        </Expander>
                    </Grid>
                </DataTemplate>
            </ListBox.Resources>
            <ListBox.ItemTemplate>
                <DataTemplate DataType="local:Field">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="60"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Path=Name}" />
                        <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=DisplayValue}" />
                        <ContentPresenter Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
                                    Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem},
                                                         Path=IsSelected, Converter={StaticResource bvc}}"
                                    x:Name="fieldTemplateDetail"
                                    Content="{Binding}"
                                    ContentTemplateSelector="{StaticResource fieldTemplateSelector}"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Grid.Row="1" x:Name="findButton" Content="Waste Button" Width="100" HorizontalAlignment="Left" Click="click_Unselect"/>
    </Grid>
</Window>

using System.ComponentModel;
namespace ListViewTemplateSelectorWPF
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    ///

    public partial class MainWindow : Window
    {
        private List<Field> fields = new List<Field>();
        public MainWindow()
        {
            fields.Add(new FieldString("String1"));
            fields.Add(new FieldString("String2"));
            fields.Add(new FieldDate("Date1"));
            fields.Add(new FieldDate("Date2"));

            InitializeComponent();
        }
        public Field CurField { get; set; }
        public List<Field> Fields { get { return fields; } }

        private void click_Unselect(object sender, RoutedEventArgs e)
        {
            try
            {
                Button tb = this.FindName("findButton") as Button;
                if (tb == null) MessageBox.Show("null");
                else MessageBox.Show(tb.Name);
            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.Message, "exception findButton");
            }
            try
            {
                DataTemplate dt = this.FindResource("fieldDateTemplate") as DataTemplate;
                if (dt == null) MessageBox.Show("dt not found");
                else MessageBox.Show("dt found");
            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.Message, "exception dt");
            }

            lbFields.SelectedIndex = -1;
        }

        private void FindTB_click(object sender, RoutedEventArgs e)
        {
            var d = sender as DependencyObject;
            while (d != null && !(d is ContentPresenter)) d = VisualTreeHelper.GetParent(d);
            var cp = d as ContentPresenter;
            if (cp != null)
            {
                var template = cp.ContentTemplate;
                if (template == null && cp.ContentTemplateSelector != null)
                    template = cp.ContentTemplateSelector.SelectTemplate(cp.Content, cp);
                if (template != null)
                {
                    var tb = template.FindName("tbFindMe", cp) as TextBox;
                    MessageBox.Show(tb.Text, "ContentTemplateSelector");
                }
            }

            Button btn = (Button)sender;
            //MessageBox.Show("button name = " + btn.Name);
            try
            {
                TextBox tb = ((Grid)btn.Parent).FindName("tbFindMe") as TextBox;
                if (tb == null) MessageBox.Show("null","manual");
                else MessageBox.Show(tb.Text, "manual");
            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.Message, "exception manual");
            }
        }
    }
    public abstract class Field : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        private string name;
        public string Name { get { return name; } }
        public abstract string DisplayValue { get; }
        public Field(string Name) { name = Name; }
    }
    public class FieldString : Field
    {
        private string fieldValue;
        public string FieldValue
        {
            get { return fieldValue; }
            set
            {
                if (fieldValue == value) return;
                fieldValue = value;
                NotifyPropertyChanged("FieldValue");
                NotifyPropertyChanged("DisplayValue");
            }
        }
        public override string DisplayValue
        {
            get { return FieldValue; }
        }
        public FieldString(string Name) : base(Name) { }
        public FieldString(string Name, string FieldValue) : base(Name)
        {   fieldValue = FieldValue; }
    }
    public class FieldDate : Field
    {
        private  DateTime? fieldValue = null;
        public DateTime? FieldValue
        {
            get { return fieldValue; }
            set
            {
                if (fieldValue == value) return;
                fieldValue = value;
                NotifyPropertyChanged("FieldValue");
                NotifyPropertyChanged("DisplayValue");
            }
        }
        public override string DisplayValue
        {
            get { return FieldValue.ToString(); }
        }
        public FieldDate(string Name)
            : base(Name) { }
        public FieldDate(string Name, DateTime FieldValue)
            : base(Name)
        { fieldValue = FieldValue; }
    }
    public class FieldTemplateSelector : DataTemplateSelector
    {
        public override DataTemplate
            SelectTemplate(object item, DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;
            if (item != null && item is Field)
            {
                System.Diagnostics.Debug.WriteLine("Field");
                if (item is FieldString)
                {
                    System.Diagnostics.Debug.WriteLine("FieldString");
                    return element.FindResource("fieldStringTemplate") as DataTemplate;
                }
                if (item is FieldDate)
                {
                    System.Diagnostics.Debug.WriteLine("FieldDate");
                    return element.FindResource("fieldDateTemplate") as DataTemplate;                }

                return element.FindResource("fieldTemplate") as DataTemplate;
            }
            else
                return element.FindResource("fieldTemplate") as DataTemplate;
        }
    }
}
解决方案

To find controls by name inside DataTemplate you need to find ContentPresenter that uses this template and call FindName on that template with found ContentPresenter:

private void Button_Click(object sender, RoutedEventArgs e)
{
   var d = sender as DependencyObject;
   ContentPresenter cp = null;
   while (d != null && !(d is ListBoxItem))
   {
       if (d is ContentPresenter) cp = d as ContentPresenter;
       d = VisualTreeHelper.GetParent(d);
   }
   if (cp != null)
   {
      cp = cp.ContentTemplate.FindName("fieldTemplateDetail", cp) as ContentPresenter;
      if (cp != null)
      {
         var template = cp.ContentTemplate;
         if (template == null && cp.ContentTemplateSelector != null)
            template = cp.ContentTemplateSelector.SelectTemplate(cp.Content, cp);
         if (template != null)
         {
            var tb = template.FindName("tbFindMe", cp) as TextBox;
         }
      }
   }
}

这篇关于查找文本框在一个DataTemplate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 09:45