WPF TabControl — создание шаблонов и создание вкладок программно

#.net #wpf #tabcontrol

#.net #wpf #tabcontrol

Вопрос:

Я создаю один элемент управления вкладками в WPF с помощью ContentTemplate.

 <TabControl x:Name="tabOrders">
        <TabControl.ContentTemplate>
            <DataTemplate x:Name="TabItemTemplate">
                <ScrollViewer Height="550" VerticalScrollBarVisibility="Auto">
                    <StackPanel Orientation="Vertical" Margin="0, 10, 0, 100">
                        <StackPanel Orientation="Horizontal" Margin="10, 20" HorizontalAlignment="Stretch">
                            <Button Width="100" Margin="0, 0, 20, 0" x:Name="btnUpload" Click="btnUpload_Click">Upload</Button>
                            <ComboBox Width="250" Margin="0, 0, 20, 0" x:Name="ddlPaperType" DataContext="{Binding paper_id }"></ComboBox>
                            <Button Width="100" Margin="0, 0, 20, 0" x:Name="btnApplyAll" Click="btnApplyAll_Click">Apply All</Button>
                        </StackPanel>
                        <ListView x:Name="lvImages" HorizontalAlignment="Stretch" VerticalAlignment="Top">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <UniformGrid Columns="5" HorizontalAlignment="Stretch"/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                        <Image Height="100" Width="100" Source="{Binding FileName}" HorizontalAlignment="Stretch" VerticalAlignment="Top" Stretch="UniformToFill" />
                                        <ComboBox x:Name="cmbPaperType" ItemsSource="{Binding paper_id}"  Margin="5" DisplayMemberPath="name" SelectedValuePath="_id" ></ComboBox>
                                        <!--<TextBlock Text="{Binding Title}" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" />-->
                                    </StackPanel>

                                </DataTemplate>
                            </ListView.ItemTemplate>

                        </ListView>
                    </StackPanel>
                </ScrollViewer>
            </DataTemplate>
        </TabControl.ContentTemplate>

    </TabControl>
 

Создание элементов вкладок с использованием приведенного ниже кода:

 tabOrders.DataContext = DataContext;

        List<TabContext> context = (List<TabContext>)DataContext;
        foreach (TabContext tabContext in context)
        {
            TabItem tabItem = new TabItem();
            tabItem.DataContext = tabContext;
            tabItem.Header = tabContext.item.order_number   " - "   tabContext.item.ProductArr.product_name ;
            tabOrders.Items.Add(tabItem);
        }
 

Здесь проблема в том, что обе вкладки отображают одинаковое содержимое. Я новичок в WPF и не знаю, чего мне не хватает. Пожалуйста, сообщите.

Обновление : 28 декабря

При нажатии кнопки я запускаю приведенный ниже код, который привязывает данные к listview:

 private void btnUpload_Click(object sender, RoutedEventArgs e)
    {
        var btn = (Button)sender;
        var parentPanel = (StackPanel)btn.Parent;
        var cmb = parentPanel.FindChild<ComboBox>("ddlPaperType");

        TabItem currentTab = (TabItem)tabOrders.Items[tabOrders.SelectedIndex];
        var context = (TabContext)currentTab.DataContext;
        cmb.ItemsSource = context.paper_id;
        cmb.DisplayMemberPath = "name";
        cmb.SelectedValuePath = "_id";

        var order_number = context.item.order_number;
        var brand_id = context.item.brand_id._id;

        var parent = btn.Parent;
        OpenFileDialog ofd = new OpenFileDialog();
        ofd.Multiselect = true;
        List<UploadFile> images = new List<UploadFile>();
        ofd.Filter = "Image Files (*.bmp, *.jpg, *.jpeg, *.tif, *.tiff)|*.bmp; *.jpg; *.jpeg; *.tif; *.tiff|Photoshp Files (*.psd)|*.psd|Text Files (*.txt)|*.txt";
        if (ofd.ShowDialog() == true)
        {
            foreach (var item in ofd.FileNames)
            {
                images.Add(new UploadFile
                {
                    FileName = item,
                    order_number = order_number,
                    brand_id = brand_id,
                    paper_id = context.paper_id
                });
            }
        }
        var lv = parent.GetParentObject().FindChild<ListView>("lvImages");
        lv.ItemsSource = images;
    }
 

Комментарии:

1. Пожалуйста, поделитесь ViewModel, связанной с этим представлением, или как вы предоставляете ListView с ItemsSource.

2. Обновленный вопрос для соответствия запрошенному коду.

3. Вы также хотите показать класс, который вы используете для предоставления DataContext. Почему бы не следовать MVVM? разделение View и ViewModel и внедрение вашей модели в представление (в codebehind, в .xaml.cs) и тестирование ваших ViewModels. То, что вы делаете, очень нечитаемо, не поддерживается. Если вы позволите мне это изображение, это немного похоже на запись на ассемблере из python. Для MVVM это означает использование ICommand для ваших кнопок и {Binding DatacontextProperty} для всего, что связано с данными. Вы хотите использовать код только тогда, когда нет взаимодействия с ViewModel (и я вижу функцию god в btnUpload_Click )

4. Попробуйте статический анализатор, такой как Ndepend, чтобы увидеть, что вы делаете неправильно в своем проекте, и вы радикально улучшите свою разработку.

5. Да, мне пришлось использовать MVVM и выполнять привязку для всех элементов управления. Это сработало так, как вы предложили. Большое спасибо.