在VB.Net动态地添加多个基于XAML WPF控件到画布(Add multiple XAML ba

2019-11-08 13:24发布

像主题,我想添加同一模板,但不同的数据中尽可能多的WPF控件我想要动态。

正如你可以在图片中看到的,我要复制的控制有些复杂。 整体控制被包裹内部CanvasScrollViewer 。 每个StackPanel包裹TextBlockanother画布控制和这个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事件等。

另外,我也不会用ListBoxListView它,因为每个控制应设在绝对X,有各种大小XY坐标值。

有一些例子做像“添加一个按钮一定的控制”类似的事情。 但我发现,只是在后端有可能不适合这种复杂的控制的硬编码的属性添加控制。

先感谢您。

Answer 1:

当你准备创建相同的用户界面无数次的思考,那么你应该考虑在模板的条款。

当你想要的任何改变的属性,那么你应该考虑在一个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));
    }
}


文章来源: Add multiple XAML based WPF control to Canvas dynamically in VB.Net