创建一个自定义模板作为ResourceDictionary并从代码隐藏访问它

时间:2014-03-05 17:19:26

标签: c# xaml windows-store-apps datatemplate resourcedictionary

我需要创建一个简单的CRUD,并且我想在不同的页面中重用相同的“模板”。

MyCrud.xaml(模板)

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<!-- disegno la mia crud-->
<DataTemplate x:Key="MyCrud">
    <StackPanel>
        <StackPanel Orientation="Horizontal" Margin="0,20,0,20">
            <TextBlock Text="Code"  FontWeight="Bold" Width="150" FontSize="24"/>
            <TextBox x:Name="edtCode" InputScope="Number" Width="300" Margin="20,0,20,0" HorizontalAlignment="Left"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal" Margin="0,20,0,20">
            <TextBlock Text="Vin" FontWeight="Bold" Width="150" FontSize="24"/>
            <TextBox x:Name="edtVin" Width="300" Margin="20,0,20,0" HorizontalAlignment="Left"/>
        </StackPanel>
        <StackPanel Orientation="Horizontal" Margin="0,20,0,20">
            <TextBlock Text="Url" FontWeight="Bold" Width="150" FontSize="24"/>
            <TextBox x:Name="edtUrl" Width="300" Margin="20,0,20,0" HorizontalAlignment="Left"/>
        </StackPanel>
    </StackPanel>
</DataTemplate>

然后我在App.xaml

中注册了它
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="View/MyCrud.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

所以现在我想将它放在一个页面中,并在我的SearchPage.xaml中使用它

SearchPage.xaml

<Page ...bla bla bla>
<ContentControl x:Name="MyTemplate" Content="{Binding}" ContentTemplate="{StaticResource MyCrud}" />
</Page>

目前布局完美无缺

问题是:

  1. 如何访问TextBox?例如,一个叫 来自SearchPage的代码隐藏的edtVin
  2. 为什么TextBox p= GetTemplateChild("edtVin") as TextBox;始终为空?
  3. 我发现这个solution,它是最好的吗?
  4. 谢谢!

2 个答案:

答案 0 :(得分:2)

  

“创建一个合适的ViewModel并使用正确的DataBinding和所有你的   问题会神奇地消失。“

DataTemplate旨在用作“某个数据元素的可视化表示”

无需来“访问”WPF中的过程代码中的任何UI元素。无论对这些元素的任何属性进行何种修改都应该使用正确的DataBinding,否则,如果手动修改UI元素的属性(不修改相应的底层数据项),则基本上是打破UI和数据之间的一致性,DataTemplate内的UI元素将不再反映数据项中的数据。

创建一个表示要在屏幕上显示的数据的简单类:

public class MyData
{
    public string Code {get;set;}

    public string Vin {get;set;}

    public string Url {get;set;}
}

然后,为了支持双向WPF DataBinding,请使用您的班级Implement the INotifyPropertyChanged interface

然后,将UI的DataContext设置为这些项目的相关实例(或集合):

public MyWindow() //Window's constructor
{
   InitializeComponent();

   var list = new List<MyData>();

   //... populate the list with data here...

   DataContext = list;
}

然后简单地操纵这些数据项的属性,同时保留UI:

var item = list[0]; //for example

item.Code = "My New Code";

这是使用WPF的正确方法。

答案 1 :(得分:1)

  

1)我如何访问TextBox,例如调用的TextBox   来自SearchPage的代码隐藏的“edtVin”?

你可以这样:

MyTemplate.ContentTemplate.FindName("edtVin", MyTemplate) as TextBox;
  

2)为什么TextBox p = GetTemplateChild(“edtVin”)为TextBox;

这返回null,因为edtVin是ContentControl的模板子项而不是Page。

  

3)我找到了解决方案,它是最好的解决方案吗?

是的,您也可以使用VisualTreeHelper方法。将它们作为实用程序函数添加到项目中,以便可以从代码中的任何位置访问它。