Динамически добавлять несколько элементов управления WPF на основе XAML в Canvas в VB.Net - PullRequest
0 голосов
/ 02 марта 2019

Как и в предмете, я хочу добавить элементы управления WPF одного и того же шаблона, но разные данные внутри столько, сколько я хочу, динамически.

Как вы можете видеть на рисунке, элемент управления, который я хочу дублироватьэто несколько сложно.Общий контроль обернут внутри Canvas внутри ScrollViewer.Каждый StackPanel упаковывает TextBlock и another Canvas Control, и это 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>

Photo explanation

Я хочу продублировать этот CanvasStack StackPanel элемент управления внутри CanvasBoard Canvas Элемент управления.

Конечно, нетпросто дублировать, но также хочу взять это под контроль.Например, измените положение, отредактируйте текст TextBlock, замените Image и получите событие Click и т. Д.

Плюс, я не буду использовать ListBox или ListViewдля этого, потому что каждый элемент управления должен быть расположен в абсолютной x, y координации с различным размером.

Есть несколько примеров, делающих подобные вещи, такие как «добавление кнопки к определенному элементу управления».Но я обнаружил лишь добавление управления в бэкэнд с жестко закодированными свойствами, которые могут не подходить для такого сложного управления.

Заранее спасибо.

1 Ответ

0 голосов
/ 02 марта 2019

Всякий раз, когда вы думаете о создании одного и того же пользовательского интерфейса много раз, вы должны думать с точки зрения шаблонов.

Когда вы хотите, чтобы свойства чего-либо менялись, вы должны думать с точки зрения таблицы данных и связывать их.изменяя вещи на открытое свойство модели представления.

При повторяющихся элементах управления в одной и той же области первым кандидатом должен быть какой-то элемент управления элементами.

В котором есть панель стека, в которой содержится все, ноВы можете легко это изменить.

Для множества вещей на одном холсте вы можете сделать панель элементов управления элементами холстом.

Вам совершенно не нужен пользовательский контроль для инкапсуляции вашей разметки, вы можетепросто имейте табличку с данными.

Создайте модель представления для своих окон.Создайте модель представления для каждой из этих вещей, которую вы хотите воспроизвести (vm).

Свяжите наблюдаемую коллекцию vm с источником элементов управления элементами.

Определите шаблон данных, связанный с этим типом модели представления.

Я работаю в 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>

Viewmodel per stack

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; }

}

Добавьте любые другие свойства, которые будут различаться для каждого стека, и свяжите их.Создайте один из них для каждого стека и добавьте его в связанную коллекцию observable:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...