像主题,我想添加同一模板,但不同的数据中尽可能多的WPF控件我想要动态。
正如你可以在图片中看到的,我要复制的控制有些复杂。 整体控制被包裹内部Canvas
内ScrollViewer
。 每个StackPanel
包裹TextBlock
和another
画布控制和这个StackPanel
是我想重现什么。
其编码,如:
<ScrollViewer x:Name="ScrollBoard" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
<Canvas x:Name="CanvasBoard" VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" Height="250" Background="Gray">
<StackPanel x:Name="CanvasStack" Background="DimGray">
<CheckBox />
<Border x:Name="CanvasBorder" BorderBrush="Black" BorderThickness="1">
<Canvas Width="150" Height="200" ClipToBounds="True">
<Image x:Name="CanvasImage" Canvas.Left="0" Canvas.Top="0" Stretch="Fill" Source="C:\test.jpg"/>
</Canvas>
</Border>
<TextBlock Text="Test.jpg" />
</StackPanel>
</Canvas>
</ScrollViewer>
我想复制该CanvasStack StackPanel
CanvasBoard内部控制Canvas
控制。
当然,不只是复制,但也希望利用该控件。 例如,改变位置,编辑TextBlock
文本,更换Image
,并得到Click事件等。
另外,我也不会用ListBox
或ListView
它,因为每个控制应设在绝对X,有各种大小XY坐标值。
有一些例子做像“添加一个按钮一定的控制”类似的事情。 但我发现,只是在后端有可能不适合这种复杂的控制的硬编码的属性添加控制。
先感谢您。
当你准备创建相同的用户界面无数次的思考,那么你应该考虑在模板的条款。
当你想要的任何改变的属性,那么你应该考虑在一个DataTemplate和方面结合这些改变事物的视图模型的公共财产。
与在同一地区重复控制第一候选人应是某种一个ItemsControl的。
这有一个StackPanel在它拥有的一切 - 但你可以很容易地改变这种状况。
对于一个帆布许多事情可以做一个ItemsControl的itemspanel的画布。
你并不绝对需要一个用户控件封装您的标记,你可以有一个DataTemplate。
建立你的窗户视图模型。 建立每个要复制(VM)这些东西视图模型。
绑定虚拟机的一个ObservableCollection到一个ItemsControl的的ItemsSource。
定义与该类型视图模型的关联一个DataTemplate。
我在C#中工作,所以我可能会得到一些错误,如果我试图写VB代码。 通过在线转换器运行下面的代码。
标记:
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<ItemsControl x:Name="ic" ItemsSource="{Binding Items}">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:StackyVM}">
<StackPanel x:Name="CanvasStack" Background="DimGray">
<CheckBox />
<Border x:Name="CanvasBorder" BorderBrush="Black" BorderThickness="1">
<Canvas Width="150" Height="200" ClipToBounds="True">
<Image x:Name="CanvasImage" Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
Source="{Binding ImageSource}"/>
</Canvas>
</Border>
<TextBlock Text="Test.jpg" />
</StackPanel>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Name="TheCanvas"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Top" Value="{Binding Top}"/>
<Setter Property="Canvas.Left" Value="{Binding Left}"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
视图模型每个堆叠
public class StackyVM : BaseViewModel
{
private Double left;
public Double Left
{
get { return left; }
set
{
left = value;
RaisePropertyChanged();
}
}
private Double top;
public Double Top
{
get { return top; }
set { top = value; RaisePropertyChanged(); }
}
public string ImageUrl { get; set; }
}
添加任何其它性质,这将对于每个堆栈变化,并且将它们绑定。 对于那些每个堆栈,并把它添加到绑定的ObservableCollection的实例化一个:
public class MainWindowViewModel : BaseViewModel
{
public ObservableCollection<StackyVM> Items { get; set; }
然后,每个将模板到堆栈。
BaseViewModel实现INotifyPropertyChanged:
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}