首页 新闻 会员 周边 捐助

WPF自定义控件如何使用

0
悬赏园豆:10 [待解决问题]

博客园里的高手老师:新年好!

我是这里的新手,也是WPF编程的新手,现在遇到的问题是,自定义控件如何使用,我是按《Practical+Wpf+Graphics+Programming》里的第八章练习做的,前面的例子都编译通过可以运行,但到最后两个案例就做不来了,我把项目附上,望高手能尽快给以回复,我愿给8分,我也不知道分给的多或少,我是初级手,分数不多,望谅,谢谢!

代码如下:

//********************** 控件的XAML 代码
<UserControl x:Class="Chapter08.LineChartControl"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
Height
="300" Width="400">
<Viewbox Stretch="Fill">
<Grid Name="grid1" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Name="column1" Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Name="row1" Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Margin="2" Grid.Column="1" Grid.Row="0"
RenderTransformOrigin
="0.5,0.5" FontSize="14"
FontWeight
="Bold" HorizontalAlignment=
"Stretch" VerticalAlignment="Stretch"
TextAlignment
="Center"
Text
="{Binding Path=Title}"/>
<TextBlock Margin="2" Grid.Column="1" Grid.Row="2"
RenderTransformOrigin
="0.5,0.5"
TextAlignment
="Center"
Text
="{Binding Path=XLabel}"/>
<TextBlock Margin="2" Grid.Column="0" Grid.Row="1"
RenderTransformOrigin
="0.5,0.5"
TextAlignment
="Center"
Text
="{Binding Path=YLabel}">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
<Canvas Name="legendCanvas" Margin="0,10,0,10"
Grid.Column
="2" Grid.Row="1" Width="40"/>
<Canvas Margin="2" Name="textCanvas" Width="300"
Height
="305" Grid.Column="1" Grid.Row="1"
ClipToBounds
="True">
<Canvas Name="chartCanvas"
ClipToBounds
="True"/>
</Canvas>
</Grid>
</Viewbox>
</UserControl>

//********************** 控件的后置 代码
using System;
using System.Windows;
using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace Chapter08
{
/// <summary>
/// LineChartControl.xaml 的交互逻辑
/// </summary>
public partial class LineChartControl : UserControl
{
private ChartStyleLineChartControl controlChartStyle;
private DataCollectionLineChartControl controlDataCollection;
private DataSeriesLineChartControl controlDataSeries;
public LineChartControl()
{
InitializeComponent();
this.DataContext = this;
this.controlChartStyle =
new ChartStyleLineChartControl(this);
this.controlDataCollection =
new DataCollectionLineChartControl(this);
this.controlDataSeries =
new DataSeriesLineChartControl();
}
public ChartStyleLineChartControl ControlChartStyle
{
get { return controlChartStyle; }
set { controlChartStyle = value; }
}
public DataCollectionLineChartControl
ControlDataCollection
{
get { return controlDataCollection; }
set { controlDataCollection = value; }
}
public DataSeriesLineChartControl ControlDataSeries
{
get { return controlDataSeries; }
set { controlDataSeries = value; }
}
public static DependencyProperty XminProperty =
DependencyProperty.Register(
"Xmin", typeof(double), typeof(LineChartControl),
new FrameworkPropertyMetadata(0.0,
new PropertyChangedCallback(OnDoubleChanged)));
public double Xmin
{
get { return (double)GetValue(XminProperty); }
set { SetValue(XminProperty, value); }
}
public static DependencyProperty XmaxProperty =
DependencyProperty.Register(
"Xmax", typeof(double), typeof(LineChartControl),
new FrameworkPropertyMetadata(1.0,
new PropertyChangedCallback(OnDoubleChanged)));
public double Xmax
{
get { return (double)GetValue(XmaxProperty); }
set { SetValue(XmaxProperty, value); }
}
public static DependencyProperty YminProperty =
DependencyProperty.Register(
"Ymin", typeof(double), typeof(LineChartControl),
new FrameworkPropertyMetadata(0.0,
new PropertyChangedCallback(OnDoubleChanged)));
public double Ymin
{
get { return (double)GetValue(YminProperty); }
set { SetValue(YminProperty, value); }
}
public static DependencyProperty YmaxProperty =
DependencyProperty.Register(
"Ymax", typeof(double), typeof(LineChartControl),
new FrameworkPropertyMetadata(1.0,
new PropertyChangedCallback(OnDoubleChanged)));
public double Ymax
{
get { return (double)GetValue(YmaxProperty); }
set { SetValue(YmaxProperty, value); }
}
public static DependencyProperty XTickProperty =
DependencyProperty.Register(
"XTick", typeof(double), typeof(LineChartControl),
new FrameworkPropertyMetadata(0.5,
new PropertyChangedCallback(OnDoubleChanged)));
public double XTick
{
get { return (double)GetValue(XTickProperty); }
set { SetValue(XTickProperty, value); }
}
public static DependencyProperty YTickProperty =
DependencyProperty.Register(
"YTick", typeof(double), typeof(LineChartControl),
new FrameworkPropertyMetadata(0.5,
new PropertyChangedCallback(OnDoubleChanged)));
public double YTick
{
get { return (double)GetValue(YTickProperty); }
set { SetValue(YTickProperty, value); }
}
public static DependencyProperty TitleProperty =
DependencyProperty.Register(
"Title", typeof(string), typeof(LineChartControl),
new FrameworkPropertyMetadata("My Chart",
new PropertyChangedCallback(OnStringChanged)));
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static DependencyProperty XLabelProperty =
DependencyProperty.Register(
"XLabel", typeof(string), typeof(LineChartControl),
new FrameworkPropertyMetadata("X Axis",
new PropertyChangedCallback(OnStringChanged)));
public string XLabel
{
get { return (string)GetValue(XLabelProperty); }
set { SetValue(XLabelProperty, value); }
}
public static DependencyProperty YLabelProperty =
DependencyProperty.Register(
"YLabel", typeof(string), typeof(LineChartControl),
new FrameworkPropertyMetadata("Y Axis",
new PropertyChangedCallback(OnStringChanged)));
public string YLabel
{
get { return (string)GetValue(YLabelProperty); }
set { SetValue(YLabelProperty, value); }
}
public static DependencyProperty IsXGridProperty =
DependencyProperty.Register(
"IsXGrid", typeof(bool), typeof(LineChartControl),
new FrameworkPropertyMetadata(true,
new PropertyChangedCallback(OnBoolChanged)));
public bool IsXGrid
{
get { return (bool)GetValue(IsXGridProperty); }
set { SetValue(IsXGridProperty, value); }
}
public static DependencyProperty IsYGridProperty =
DependencyProperty.Register(
"IsYGrid", typeof(bool), typeof(LineChartControl),
new FrameworkPropertyMetadata(true,
new PropertyChangedCallback(OnBoolChanged)));
public bool IsYGrid
{
get { return (bool)GetValue(IsYGridProperty); }
set { SetValue(IsYGridProperty, value); }
}
public static DependencyProperty GridlineColorProperty
= DependencyProperty.Register(
"GridlineColor", typeof(Brush),
typeof(LineChartControl),
new FrameworkPropertyMetadata(Brushes.Gray,
new PropertyChangedCallback(OnColorChanged)));
public Brush GridlineColor
{
get { return (Brush)GetValue(GridlineColorProperty); }
set { SetValue(GridlineColorProperty, value); }
}
public static DependencyProperty GridlinePatternProperty =
DependencyProperty.Register(
"GridLinePattern", typeof(
ChartStyleLineChartControl.GridlinePatternEnum),
typeof(LineChartControl),
new FrameworkPropertyMetadata(
ChartStyleLineChartControl.GridlinePatternEnum.Solid,
new PropertyChangedCallback(OnGridlinePatternChanged)));
public ChartStyleLineChartControl.GridlinePatternEnum
GridlinePattern
{
get { return (ChartStyleLineChartControl.
GridlinePatternEnum)GetValue(
GridlinePatternProperty); }
set { SetValue(GridlinePatternProperty, value); }
}
private static void OnGridlinePatternChanged(
DependencyObject sender,
DependencyPropertyChangedEventArgs e)
{
LineChartControl lcc
= (LineChartControl)sender;
lcc.GridlinePattern
= (ChartStyleLineChartControl.
GridlinePatternEnum)e.NewValue;
}
private static void OnColorChanged(DependencyObject
sender, DependencyPropertyChangedEventArgs e)
{
LineChartControl lcc
= (LineChartControl)sender;
lcc.GridlineColor
= (Brush)e.NewValue;
}
private static void OnDoubleChanged(DependencyObject
sender, DependencyPropertyChangedEventArgs e)
{
LineChartControl lcc
= (LineChartControl)sender;
if (e.Property == XminProperty)
lcc.Xmin
= (double)e.NewValue;
else if (e.Property == XmaxProperty)
lcc.Xmax
= (double)e.NewValue;
else if (e.Property == YminProperty)
lcc.Ymin
= (double)e.NewValue;
else if (e.Property == YmaxProperty)
lcc.Ymax
= (double)e.NewValue;
else if (e.Property == XTickProperty)
lcc.XTick
= (double)e.NewValue;
else if (e.Property == YTickProperty)
lcc.YTick
= (double)e.NewValue;
}
private static void OnStringChanged(DependencyObject
sender, DependencyPropertyChangedEventArgs e)
{
LineChartControl lcc
= (LineChartControl)sender;
if (e.Property == TitleProperty)
{
lcc.Title
= (string)e.NewValue;
}
else if (e.Property == XLabelProperty)
{
lcc.XLabel
= (string)e.NewValue;
}
else if (e.Property == YLabelProperty)
{
lcc.YLabel
= (string)e.NewValue;
}
}
private static void OnBoolChanged(DependencyObject
sender, DependencyPropertyChangedEventArgs e)
{
LineChartControl lcc
= (LineChartControl)sender;
if (e.Property == IsXGridProperty)
lcc.IsXGrid
= (bool)e.NewValue;
else if (e.Property == IsYGridProperty)
lcc.IsYGrid
= (bool)e.NewValue;
}
//**************************************************
public class ChartStyleLineChartControl
{
private double Xmin;
private double Xmax;
private double Ymin;
private double Ymax;
private string Title;
private string XLabel;
private string YLabel;
private double XTick;
private double YTick;
private bool IsXGrid;
private bool IsYGrid;
private Brush GridlineColor;
private GridlinePatternEnum GridlinePattern;
private double leftOffset = 20;
private double bottomOffset = 15;
private double rightOffset = 10;
private Line gridline = new Line();
private LineChartControl lcc;
private Canvas TextCanvas;
private Canvas ChartCanvas;
public ChartStyleLineChartControl(
LineChartControl lcc)
{
this.lcc = lcc;
TextCanvas
= lcc.textCanvas;
ChartCanvas
= lcc.chartCanvas;
UpdateChartStyle();
}
public void UpdateChartStyle()
{
Xmin
= lcc.Xmin;
Xmax
= lcc.Xmax;
Ymin
= lcc.Ymin;
Ymax
= lcc.Ymax;
XTick
= lcc.XTick;
YTick
= lcc.YTick;
Title
= lcc.Title;
XLabel
= lcc.XLabel;
YLabel
= lcc.YLabel;
IsXGrid
= lcc.IsXGrid;
IsYGrid
= lcc.IsYGrid;
GridlineColor
= lcc.GridlineColor;
GridlinePattern
= lcc.GridlinePattern;
}
public void AddChartStyle()
{
UpdateChartStyle();
Point pt
= new Point();
Line tick
= new Line();
double offset = 0;
double dx, dy;
TextBlock tb
= new TextBlock();
// determine right offset:
tb.Text = Xmax.ToString();
tb.Measure(
new Size(Double.PositiveInfinity,
Double.PositiveInfinity));
Size size
= tb.DesiredSize;
rightOffset
= size.Width / 2 + 2;
// Determine left offset:
for (dy = Ymin; dy <= Ymax; dy += YTick)
{
pt
= NormalizePoint(new Point(Xmin, dy));
tb
= new TextBlock();
tb.Text
= dy.ToString();
tb.TextAlignment
= TextAlignment.Right;
tb.Measure(
new Size(Double.PositiveInfinity,
Double.PositiveInfinity));
size
= tb.DesiredSize;
if (offset < size.Width)
offset
= size.Width;
}
leftOffset
= offset + 5;
Canvas.SetLeft(ChartCanvas, leftOffset);
Canvas.SetBottom(ChartCanvas, bottomOffset);
ChartCanvas.Width
= TextCanvas.Width -
leftOffset
- rightOffset;
ChartCanvas.Height
= TextCanvas.Height -
bottomOffset
-size.Height / 2;
Rectangle chartRect
= new Rectangle();
chartRect.Stroke
= Brushes.Black;
chartRect.Width
= ChartCanvas.Width;
chartRect.Height
= ChartCanvas.Height;
ChartCanvas.Children.Add(chartRect);
// Create vertical gridlines:
if (IsYGrid == true)
{
for (dx = Xmin + XTick; dx < Xmax; dx += XTick)
{
gridline
= new Line();
AddLinePattern();
gridline.X1
= NormalizePoint(
new Point(dx, Ymin)).X;
gridline.Y1
= NormalizePoint(
new Point(dx, Ymin)).Y;
gridline.X2
= NormalizePoint(
new Point(dx, Ymax)).X;
gridline.Y2
= NormalizePoint(
new Point(dx, Ymax)).Y;
ChartCanvas.Children.Add(gridline);
}
}
// Create horizontal gridlines:
if (IsXGrid == true)
{
for (dy = Ymin + YTick; dy < Ymax; dy += YTick)
{
gridline
= new Line();
AddLinePattern();
gridline.X1
= NormalizePoint(
new Point(Xmin, dy)).X;
gridline.Y1
= NormalizePoint(
new Point(Xmin, dy)).Y;
gridline.X2
= NormalizePoint(
new Point(Xmax, dy)).X;
gridline.Y2
= NormalizePoint(
new Point(Xmax, dy)).Y;
ChartCanvas.Children.Add(gridline);
}
}
// Create x-axis tick marks:
for (dx = Xmin; dx <= Xmax; dx += XTick)
{
pt
= NormalizePoint(new Point(dx, Ymin));
tick
= new Line();
tick.Stroke
= Brushes.Black;
tick.X1
= pt.X;
tick.Y1
= pt.Y;
tick.X2
= pt.X;
tick.Y2
= pt.Y - 5;
ChartCanvas.Children.Add(tick);
tb
= new TextBlock();
tb.Text
= dx.ToString();
tb.Measure(
new Size(Double.PositiveInfinity,
Double.PositiveInfinity));
size
= tb.DesiredSize;
TextCanvas.Children.Add(tb);
Canvas.SetLeft(tb, leftOffset
+ pt.X - size.Width / 2);
Canvas.SetTop(tb, pt.Y
+ 2 + size.Height / 2);
}
// Create y-axis tick marks:
for (dy = Ymin; dy <= Ymax; dy += YTick)
{
pt
= NormalizePoint(new Point(Xmin, dy));
tick
= new Line();
tick.Stroke
= Brushes.Black;
tick.X1
= pt.X;
tick.Y1
= pt.Y;
tick.X2
= pt.X + 5;
tick.Y2
= pt.Y;
ChartCanvas.Children.Add(tick);
tb
= new TextBlock();
tb.Text
= dy.ToString();
tb.Measure(
new Size(Double.PositiveInfinity,
Double.PositiveInfinity));
size
= tb.DesiredSize;
TextCanvas.Children.Add(tb);
Canvas.SetRight(tb, ChartCanvas.Width
+ 10);
Canvas.SetTop(tb, pt.Y);
}
}
public void AddLinePattern()
{
gridline.Stroke
= GridlineColor;
gridline.StrokeThickness
= 1;
switch (GridlinePattern)
{
case GridlinePatternEnum.Dash:
gridline.StrokeDashArray
=
new DoubleCollection(new double[2] { 4, 3 });
break;
case GridlinePatternEnum.Dot:
gridline.StrokeDashArray
=
new DoubleCollection( new double[2] { 1, 2 });
break;
case GridlinePatternEnum.DashDot:
gridline.StrokeDashArray
=
new DoubleCollection(new double[4] { 4, 2, 1, 2 });
break;
}
}
public Point NormalizePoint(Point pt)
{
if (ChartCanvas.Width.ToString() == "NaN")
ChartCanvas.Width
= 270;
if (ChartCanvas.Height.ToString() == "NaN")
ChartCanvas.Height
= 250;
Point result
= new Point();
result.X
= (pt.X -Xmin) *
ChartCanvas.Width
/ (Xmax - Xmin);
result.Y
= ChartCanvas.Height - (pt.Y - Ymin) *
ChartCanvas.Height
/ (Ymax - Ymin);
return result;
}
public enum GridlinePatternEnum
{
Solid
= 1,
Dash
= 2,
Dot
= 3,
DashDot
= 4
}
}
//****************************************
public class DataSeriesLineChartControl
{
private Polyline lineSeries = new Polyline();
private Brush lineColor;
private double lineThickness = 1;
private LinePatternEnum linePattern;
private string seriesName = "Default Name";
public DataSeriesLineChartControl()
{
LineColor
= Brushes.Black;
}
public Brush LineColor
{
get { return lineColor; }
set { lineColor = value; }
}
public Polyline LineSeries
{
get { return lineSeries; }
set { lineSeries = value; }
}
public double LineThickness
{
get { return lineThickness; }
set { lineThickness = value; }
}
public LinePatternEnum LinePattern
{
get { return linePattern; }
set { linePattern = value; }
}
public string SeriesName
{
get { return seriesName; }
set { seriesName = value; }
}
public void AddLinePattern()
{
LineSeries.Stroke
= LineColor;
LineSeries.StrokeThickness
= LineThickness;
switch (LinePattern)
{
case LinePatternEnum.Dash:
LineSeries.StrokeDashArray
=
new DoubleCollection(
new double[2] { 4, 3 });
break;
case LinePatternEnum.Dot:
LineSeries.StrokeDashArray
=
new DoubleCollection(
new double[2] { 1, 2 });
break;
case LinePatternEnum.DashDot:
LineSeries.StrokeDashArray
=
new DoubleCollection(
new double[4] { 4, 2, 1, 2 });
break;
case LinePatternEnum.None:
LineSeries.Stroke
= Brushes.Transparent;
break;
}
}
public enum LinePatternEnum
{
Solid
= 1,
Dash
= 2,
Dot
= 3,
DashDot
= 4,
None
= 5
}
}
//****************************************
public class DataCollectionLineChartControl
{
private List<DataSeriesLineChartControl> DataList;
private LineChartControl lcc;
private ChartStyleLineChartControl cs;
public DataCollectionLineChartControl(
LineChartControl lcc)
{
dataList
= new List<DataSeriesLineChartControl>();
this.lcc = lcc;
this.cs = lcc.ControlChartStyle;
}
public List<DataSeriesLineChartControl> dataList
{
get { return dataList; }
set { dataList = value; }
}
public void AddLines()
{
lcc.ControlChartStyle.AddChartStyle();
int j = 0;
foreach (DataSeriesLineChartControl ds in DataList)
{
if (ds.SeriesName == "Default Name")
{
ds.SeriesName
= "DataSeries" + j.ToString();
}
ds.AddLinePattern();
for (int i = 0; i < ds.LineSeries.Points.Count; i++)
{
ds.LineSeries.Points[i]
=
cs.NormalizePoint(
ds.LineSeries.Points[i]);
}
lcc.chartCanvas.Children.Add(ds.LineSeries);
j
++;
}
}
}
}
}

//********************** WPF 的应用 代码
<Window x:Class="Chapter08.TestLineChartControl"
xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local
="clr-namespace:Chapter08;assembly = LineChartControl"
//上面这句local ="clr-namespace:Chapter08有时也有下划线,有时不理会也可编译通过
Title
="Test LineChartControl" Height="350" Width="400">
<Grid>
<local:LineChartControl Name="myLineChart"
//上面语句local:LineChartControl 出现下划线
Xmin
="0" Xmax="7" Ymin="-1.5" Ymax="1.5"
XTick
="1" YTick="0.5"
Width
="350" Height="300"
Title
="Sine and Cosine Chart"
GridlinePattern
="Dash"/>
</Grid>
</Window>

//********************** 后置 代码
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
//using LineChartControl;

namespace Chapter08
{
public partial class TestLineChartControl : Window
{
private DataSeriesLineChartControl ds;
public TestLineChartControl()
{
InitializeComponent();
AddChart();
}
private void AddChart()
{
// Draw Sine curve:
ds = new DataSeriesLineChartControl();
//在工程项目里上面语句下DataSeriesLineChartControl出现下划线
//以下有DataSeriesLineChartControl都出错
ds.LineColor
= Brushes.Blue;
ds.LineThickness
= 3;
for (int i = 0; i < 70; i++)
{
double x = i / 5.0;
double y = Math.Sin(x);
ds.LineSeries.Points.Add(
new Point(x, y));
}
myLineChart.ControlDataCollection.
DataList.Add(ds);
//这个DataList也是
// Draw cosine curve:
ds = new DataSeriesLineChartControl();
ds.LineColor
= Brushes.Red;
ds.LinePattern
= DataSeriesLineChartControl.
LinePatternEnum.DashDot;
ds.LineThickness
= 3;
for (int i = 0; i < 70; i++)
{
double x = i / 5.0;
double y = Math.Cos(x);
ds.LineSeries.Points.Add(
new Point(x, y));
}
myLineChart.ControlDataCollection.
DataList.Add(ds);
myLineChart.ControlDataCollection.AddLines();
}
}
}


 

williamZ的主页 williamZ | 初学一级 | 园豆:200
提问于:2011-02-10 17:20
< >
分享
所有回答(2)
0

I want to know ,too,now ....

Hurry Jiang | 园豆:205 (菜鸟二级) | 2011-04-04 22:36
0

自定义控件也是空间啊。在工具箱找!没有的话,导入dll文件!

CarsonCui | 园豆:162 (初学一级) | 2012-06-05 16:39
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册