×
Namespaces

Variants
Actions

Windows Phone创建Custom Control(2)

From Nokia Developer Wiki
Jump to: navigation, search
WP Metro Icon UI.png
SignpostIcon WP7 70px.png
Article Metadata

代码示例
兼容于
文章
WS - OtomiiLu 在 05 Sep 2012 创建
最后由 hamishwillee 在 03 Jul 2013 编辑

本文主要是描述如何创建一个直接继承自Control控件的CustomGrid。 因为在Windows Phone的程序中并没有像Silverlight中的DataGrid控件。所以当我们想要显示信息的时候必须选择ListBox。因此,在这里我将尝试如何去做一个自定义的DataGrid。

CustomGrid的Style

首先,在Project中创建Themes文件夹,然后在Themes创建generic.xaml文件,这个文件默认为Custom control获取界面的地方。 然后,直接为我们的控件定义一个Style:

    <Style TargetType="local:CusGrid">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CusGrid">
<ScrollViewer x:Name="CanvasScrollViewer" Background="Gray" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<Canvas x:Name="DisplayCanvas">
 
</Canvas>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

在这个Style中不难发现,我们真实的显示,是一个ScrollViewer中嵌套一个Canvas,然后通过Canvas来显示所有的数据。 同时,我们命名外面的ScrollViewer为CanvasScrollViewer,里面的Canvas为DisplayCanvas。

CustomGrid的Code

创建一个CusGrid:

    [TemplatePart(Name = "CanvasScrollViewer", Type = typeof(ScrollViewer))]
[TemplatePart(Name = "DisplayCanvas", Type = typeof(Canvas))]
public class CusGrid : Control

上面的代码附加了两个TemplatePart,TemplatePart的主要作用就是在代码中读取Template中的元素,他们分别为CanvasScrollViewer和DisplayCanvas。然后,在OnApplyTemplate()方法中正式的获取他们:

        public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.DisplayCanvas = this.GetTemplateChild("DisplayCanvas") as Canvas;
this.CanvasScrollViewer = this.GetTemplateChild("CanvasScrollViewer") as ScrollViewer; }

然后我提供了两个类,一个是CusCol,代表所有的column:

    public class CusCol
{
public string ColName { get; set; }
public double ColWight { get; set; }
public ColType ColType { get; set; }
}

然后是ColType类,主要指定是哪种数据类型。

    public enum ColType
{
StringType
}

接着,我提供了两个方法CalCusGrid和DrawCusGrid: CalCusGrid主要是用来计算一些数据的,同时,因为我们的数据源可能是所有类型的,所以我们需要用反射来实现,本方法主要的功能是获取方法(MethodInfo)集合和获取CusCol的集合:

        private void CalCusGrid()
{
if (itemsSource[0] == null) return;
Type itemType = itemsSource[0].GetType();
PropertyInfo[] pi = itemsSource[0].GetType().GetProperties();
foreach (PropertyInfo prop in pi)
{
CusColList.Add(new CusCol() { ColName = prop.Name, ColWight = 200, ColType = ColType.StringType });
MIList.Add(itemType.GetMethod("get_" + prop.Name));
}
}

DrawCusGrid主要是用来画出我们的CusGrid的,通过遍历,创建TextBlock,并添加到界面上:

        private void DrawCusGrid()
{
for (int cuX = 0; cuX < MIList.Count; cuX++)
{
if (CusColList[cuX].ColType.Equals(ColType.StringType))
{
for (int cuY = 0; cuY < itemsSource.Count; cuY++)
{
TextBlock tb = new TextBlock();
tb.Text = MIList[cuX].Invoke(itemsSource[cuY], null).ToString();
Canvas.SetLeft(tb, (CusColList[cuX].ColWight + 10) * cuX);
Canvas.SetTop(tb, cuY * 60);
DisplayCanvas.Children.Add(tb);
if (cuX == MIList.Count - 1 && cuY == itemsSource.Count - 1)
{
DisplayCanvas.Height = (cuY + 1) * 60;
DisplayCanvas.Width = (CusColList[cuX].ColWight + 10) * (cuX+1);
}
}
}
 
}
}

这样,我们的控件就完成了,以下是如何使用控件。

使用控件

首先创建一个类Customer:

  public class Customer
{
public String FirstName { get; set; }
public String LastName { get; set; }
public String Address { get; set; }
public Boolean IsNew { get; set; }
 
// A null value for IsSubscribed can indicate
// "no preference" or "no response".
public Boolean IsSubscribed { get; set; }
 
public Customer(String firstName, String lastName,
String address, Boolean isNew, Boolean isSubscribed)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Address = address;
this.IsNew = isNew;
this.IsSubscribed = isSubscribed;
}
 
public static List<Customer> GetSampleCustomerList()
{
return new List<Customer>(new Customer[] {
new Customer("A.", "Zero",
"Apartment 45",
false, true),
new Customer("B.", "One",
"Apartment 67",
false, false),
new Customer("C.", "Two",
"Apartment 89",
true, false),
new Customer("D.", "Three",
"Apartment 10",
true, true),
new Customer("A.", "Zero",
"Apartment 45",
false, true),
new Customer("A.", "Zero",
"Apartment 45",
false, true),
new Customer("B.", "One",
"Apartment 67",
false, false),
new Customer("C.", "Two",
"Apartment 89",
true, false),
new Customer("D.", "Three",
"Apartment 10",
true, true),
new Customer("A.", "Zero",
"Apartment 45",
false, true),
new Customer("A.", "Zero",
"Apartment 45",
false, true),
new Customer("B.", "One",
"Apartment 67",
false, false),
new Customer("C.", "Two",
"Apartment 89",
true, false),
new Customer("D.", "Three",
"Apartment 10",
true, true),
new Customer("A.", "Zero",
"Apartment 45",
false, true),
new Customer("A.", "Zero",
"Apartment 45",
false, true),
new Customer("B.", "One",
"Apartment 67",
false, false),
new Customer("C.", "Two",
"Apartment 89",
true, false),
new Customer("D.", "Three",
"Apartment 10",
true, true),
new Customer("A.", "Zero",
"Apartment 45",
false, true),
new Customer("A.", "Zero",
"Apartment 45",
false, true)
});
}
}

在这个类中,可以通过 GetSampleCustomerList()方法获取到一个Customer类的集合。 然后在MainPage的界面上添加我们创建好的控件,并这是Name为cusGrid

    <Grid x:Name="LayoutRoot" Background="Transparent">
<Lib:CusGrid Width="400" Height="600" Name="cusGrid">
 
</Lib:CusGrid>
</Grid>

最后直接为cusGrid的ItemsSource赋值,即可设置控件的数据源:

public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
cusGrid.ItemsSource = Customer.GetSampleCustomerList();
}
}

运行项目,发现成功了,所有的数据已经显示在了界面上:

项目截图:

CustomGrid.JPG

项目源文件:

File:CustomGrid.zip

This page was last modified on 3 July 2013, at 06:48.
132 page views in the last 30 days.