创建通用模板
Create a template for general use
我创建了一个 RadCartesianChart 来绘制条形图系列。 xaml代码是:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<telerik:RadCartesianChart x:Name="chart" Width="400" Height="300">
<telerik:RadCartesianChart.VerticalAxis>
<telerik:LinearAxis/>
</telerik:RadCartesianChart.VerticalAxis>
<telerik:RadCartesianChart.HorizontalAxis>
<telerik:CategoricalAxis/>
</telerik:RadCartesianChart.HorizontalAxis>
<telerik:RadCartesianChart.Series>
<telerik:BarSeries CategoryBinding="Category" ValueBinding="Value" ItemsSource="{Binding}">
<telerik:BarSeries.DefaultVisualStyle>
<Style TargetType="Border">
<Setter Property="Background" Value="{Binding DataItem.Color}" />
</Style>
</telerik:BarSeries.DefaultVisualStyle>
</telerik:BarSeries>
</telerik:RadCartesianChart.Series>
</telerik:RadCartesianChart>
</Grid>
以及
背后的代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = GetData(12);
}
public static List<ChartData> GetData(int dataSize)
{
Random rnd = new Random();
var result = new List<ChartData>();
for (int i = 0; i < dataSize; i++)
{
result.Add(new ChartData()
{
Category = i,
Value = rnd.Next(1, 100),
Color = new SolidColorBrush(
Color.FromArgb(255, (byte)rnd.Next(0, 256), (byte)rnd.Next(0, 256), (byte)rnd.Next(0, 256)))
});
}
return result;
}
}
public class ChartData : INotifyPropertyChanged
{
private int _category;
public int Category
{
get { return this._category; }
set { this._category = value;
this.OnPropertyChanged("Category"); }
}
private double _value;
public double Value
{
get { return this._value; }
set { this._value = value; this.OnPropertyChanged("Value"); }
}
private Brush _color;
public Brush Color
{
get { return this._color; }
set { this._color = value; this.OnPropertyChanged("Color"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
我的问题是如何使用用户控件作为模板?原因是我们有非常相似的案例要绘制。我们是否需要为每个单独的控件创建许多用户控件,或者我们可以创建一个模板来引用它?
我不擅长 contentpresenter
或 ContentControl
或 ControlTemplate
之类的。
您可以使用DataTemplate,根据需要定义多个数据模板,并根据Trigger切换ContentControl的ContentTemplate。
假设我们有一个带有 ContentControl 的 XAML 文件。
<UserControl.Resources>
<DataTemplate x:Key="DataTemplate1">
<!-- your code for control goes here-->
</DataTemplate>
<DataTemplate x:Key="DataTemplate2">
<!-- your code for control goes here-->
</DataTemplate>
<Style x:Key="ContentControlStyle" TargetType="{x:Type ContentControl}">
<!-- Default content for content control would be DataTemplate1 -->
<Setter Property="ContentTemplate" Value="{StaticResource DataTemplate1}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SomePropertyInViewModel}" Value="YourValue">
<!-- If SomePropertyInViewModel == YourValue in ViewModel DataTemplate2 will be applied.-->
<Setter Property="ContentTemplate" Value="{StaticResource DataTemplate2}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<ContentControl Style="{StaticResource ContentControlStyle}"/>
如有任何其他问题,请告诉我。
声明一个 Style
,例如 App.xaml
:
<Style x:Key="myStyle" TargetType="telerik:RadCartesianChart">
<Setter Property="Width" Value="400" />
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAxis">
<Setter.Value>
<telerik:LinearAxis/>
</Setter.Value>
</Setter>
<Setter Property="HorizontalAxis">
<Setter.Value>
<telerik:CategoricalAxis/>
</Setter.Value>
</Setter>
<Setter Property="Series">
<Setter.Value>
<telerik:BarSeries CategoryBinding="Category" ValueBinding="Value" ItemsSource="{Binding}">
<telerik:BarSeries.DefaultVisualStyle>
<Style TargetType="Border">
<Setter Property="Background" Value="{Binding DataItem.Color}" />
</Style>
</telerik:BarSeries.DefaultVisualStyle>
</telerik:BarSeries>
</Setter.Value>
</Setter>
</Style>
...并使用 x:Key
:
将 Style
应用于任何 RadCartesianChart
<telerik:RadCartesianChart x:Name="chart" Style="{StaticResource myStyle}" />
我创建了一个 RadCartesianChart 来绘制条形图系列。 xaml代码是:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<telerik:RadCartesianChart x:Name="chart" Width="400" Height="300">
<telerik:RadCartesianChart.VerticalAxis>
<telerik:LinearAxis/>
</telerik:RadCartesianChart.VerticalAxis>
<telerik:RadCartesianChart.HorizontalAxis>
<telerik:CategoricalAxis/>
</telerik:RadCartesianChart.HorizontalAxis>
<telerik:RadCartesianChart.Series>
<telerik:BarSeries CategoryBinding="Category" ValueBinding="Value" ItemsSource="{Binding}">
<telerik:BarSeries.DefaultVisualStyle>
<Style TargetType="Border">
<Setter Property="Background" Value="{Binding DataItem.Color}" />
</Style>
</telerik:BarSeries.DefaultVisualStyle>
</telerik:BarSeries>
</telerik:RadCartesianChart.Series>
</telerik:RadCartesianChart>
</Grid>
以及
背后的代码using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = GetData(12);
}
public static List<ChartData> GetData(int dataSize)
{
Random rnd = new Random();
var result = new List<ChartData>();
for (int i = 0; i < dataSize; i++)
{
result.Add(new ChartData()
{
Category = i,
Value = rnd.Next(1, 100),
Color = new SolidColorBrush(
Color.FromArgb(255, (byte)rnd.Next(0, 256), (byte)rnd.Next(0, 256), (byte)rnd.Next(0, 256)))
});
}
return result;
}
}
public class ChartData : INotifyPropertyChanged
{
private int _category;
public int Category
{
get { return this._category; }
set { this._category = value;
this.OnPropertyChanged("Category"); }
}
private double _value;
public double Value
{
get { return this._value; }
set { this._value = value; this.OnPropertyChanged("Value"); }
}
private Brush _color;
public Brush Color
{
get { return this._color; }
set { this._color = value; this.OnPropertyChanged("Color"); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
我的问题是如何使用用户控件作为模板?原因是我们有非常相似的案例要绘制。我们是否需要为每个单独的控件创建许多用户控件,或者我们可以创建一个模板来引用它?
我不擅长 contentpresenter
或 ContentControl
或 ControlTemplate
之类的。
您可以使用DataTemplate,根据需要定义多个数据模板,并根据Trigger切换ContentControl的ContentTemplate。
假设我们有一个带有 ContentControl 的 XAML 文件。
<UserControl.Resources>
<DataTemplate x:Key="DataTemplate1">
<!-- your code for control goes here-->
</DataTemplate>
<DataTemplate x:Key="DataTemplate2">
<!-- your code for control goes here-->
</DataTemplate>
<Style x:Key="ContentControlStyle" TargetType="{x:Type ContentControl}">
<!-- Default content for content control would be DataTemplate1 -->
<Setter Property="ContentTemplate" Value="{StaticResource DataTemplate1}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding SomePropertyInViewModel}" Value="YourValue">
<!-- If SomePropertyInViewModel == YourValue in ViewModel DataTemplate2 will be applied.-->
<Setter Property="ContentTemplate" Value="{StaticResource DataTemplate2}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<ContentControl Style="{StaticResource ContentControlStyle}"/>
如有任何其他问题,请告诉我。
声明一个 Style
,例如 App.xaml
:
<Style x:Key="myStyle" TargetType="telerik:RadCartesianChart">
<Setter Property="Width" Value="400" />
<Setter Property="Width" Value="100" />
<Setter Property="VerticalAxis">
<Setter.Value>
<telerik:LinearAxis/>
</Setter.Value>
</Setter>
<Setter Property="HorizontalAxis">
<Setter.Value>
<telerik:CategoricalAxis/>
</Setter.Value>
</Setter>
<Setter Property="Series">
<Setter.Value>
<telerik:BarSeries CategoryBinding="Category" ValueBinding="Value" ItemsSource="{Binding}">
<telerik:BarSeries.DefaultVisualStyle>
<Style TargetType="Border">
<Setter Property="Background" Value="{Binding DataItem.Color}" />
</Style>
</telerik:BarSeries.DefaultVisualStyle>
</telerik:BarSeries>
</Setter.Value>
</Setter>
</Style>
...并使用 x:Key
:
Style
应用于任何 RadCartesianChart
<telerik:RadCartesianChart x:Name="chart" Style="{StaticResource myStyle}" />