Несколько DataContext один TreeView, один DataGrid, оба не могут быть активными одновременно - PullRequest
1 голос
/ 03 августа 2020

Я создал древовидное представление после видео на YouTube, а затем создал сетку данных, которая показывает некоторые файлы из выбранного файла tar.gz. Оба они используют DataContext, чтобы показать себя в программе. Проблема в том, что TreeView исчезает, когда отображается DataGrid. Думаю, проблема в том, что оба не могут использовать DataContext, как я использую, но я не знаю решения для этого.

Код XAML

<Window x:Class="RFAnalyzerMain.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:RFAnalyzerMain"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="600" Width="900"
        MinHeight="400" MinWidth="750"
        Closing="Window_Closing" Loaded="Window_Loaded">
    <Border Padding="2">
        <Grid>
            <!-- #region Grid Definitions -->

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="200" />
                <ColumnDefinition Width="10*" />
                <ColumnDefinition Width="15" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
                <RowDefinition Height="25*" />
                <RowDefinition Height="20" />
            </Grid.RowDefinitions>

            <!--#endregion-->

            <DockPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
                <Menu DockPanel.Dock="Top">
                    <MenuItem Header="_File">
                        <MenuItem Header="Choose File to Read" x:Name="ChosenFile" Click="ChosenFile_Click" />
                    </MenuItem>
                </Menu>
            </DockPanel>

            <Border Grid.Row="2" Padding="5 0" BorderThickness="0" BorderBrush="Gray">
                <Grid>

                    <!-- Grid Definitions -->
                    <Grid.RowDefinitions>
                        <RowDefinition Height="25" />
                        <RowDefinition Height="*" />
                        <RowDefinition Height="20" />
                    </Grid.RowDefinitions>

                    <TextBlock Text="Folder" FontWeight="Bold" FontSize="18" Grid.Row="0"
                       VerticalAlignment="Center" HorizontalAlignment="Left" />

                    <!-- A TreeView of Fodlers -->
                    <Grid Grid.Row="1" Margin="0 0 0 5">
                        <TreeView x:Name="FolderView" ItemsSource="{Binding Items}" FontSize="10">
                            
                            <TreeView.ItemContainerStyle>
                                <Style TargetType="{x:Type TreeViewItem}">
                                    <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
                                </Style>
                            </TreeView.ItemContainerStyle>

                            <TreeView.ItemTemplate>
                                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                                    <StackPanel Orientation="Horizontal">
                                        <Image Width="15" Margin="3"
                                                   Source="{Binding Type,
                                                       Converter={x:Static local:HeaderToImageConverter.Instance}}" />
                                        <TextBlock VerticalAlignment="Center" Text="{Binding Name}" />
                                    </StackPanel>
                                </HierarchicalDataTemplate>
                            </TreeView.ItemTemplate>
                            
                        </TreeView>
                    </Grid>


                    <Button Content="Read" Grid.Row="2" Margin="0 0 0 0" Width="60" />
                </Grid>
            </Border>

            <DataGrid Grid.Row="2" Grid.Column="1" ItemsSource="{Binding FileProperties}" />

            <Button Grid.Column="2" Grid.Row="2">
                <Image Source="Images/Button Left Arrow.png" Width="10" />
            </Button>

        </Grid>
    </Border>
</Window>

Behind-Code

using System.IO;
using System.Windows;

namespace RFAnalyzerMain
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        #region Constructor

        /// <summary>
        /// Default Constructor
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
            // Treeview
            DataContext = new DirectoryStructureViewModel();
        }

        #endregion

        #region User Events

        /// <summary>
        /// Choose a file from the explorer
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ChosenFile_Click(object sender, RoutedEventArgs e)
        {
            ExplorerHandler.OpenExplorer();
            // Writes out all the files inside the file opened in the explorer
            DataContext = new FilePropertiesViewModel();
        }

        #endregion

        #region Starting Program

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (FilePaths.GZipDirectory.Exists == true)
                Remove.FilesAndFolders();
        }

        #endregion

        #region Closing Program

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            Remove.FilesAndFolders();
        }

        #endregion


    }
}

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

Ответы [ 2 ]

1 голос
/ 03 августа 2020

Поскольку вы реализовали свой logi c в коде программной части, почему бы вам просто не установить DataContext из DataGrid в обработчике событий?:

private void ChosenFile_Click(object sender, RoutedEventArgs e)
{
    ExplorerHandler.OpenExplorer();
    // Writes out all the files inside the file opened in the explorer
    dataGrid.DataContext = new FilePropertiesViewModel();
}

XAML:

<DataGrid x:Name="dataGrid" Grid.Row="2" Grid.Column="1" ItemsSource="{Binding FileProperties}" />

Тогда TreeView не исчезнет, ​​когда вы нажмете кнопку.

Другой вариант - использовать модель общего представления, как предлагается от @Sinatr, но это потребует некоторого рефакторинга по сравнению с тем, что у вас сейчас есть.

0 голосов
/ 03 августа 2020

Обычно вы должны установить DataContext один раз:

public MainWindow()
{
    InitializeComponent();
    DataContext = new MainWindowViewModel();
}

Модель представления может иметь несколько свойств:

public class MainWindowViewModel: INotifyPropertyChanaged
{
    public DirectoryStructureViewModel Files { get; } = new DirectoryStructureViewModel();

    FilePropertiesViewModel _selectedFile;
    public FilePropertiesViewModel SelectedFile
    {
        get => _selectedFile;
        set
        {
            _selectedFile = value;
            OnPropertyChanged();
            OnPropertyChanged(nameof(IsSelectedFileVisible));
        }
    }
    public bool IsSelectedFileVisible => SelectedFile != null;
}

К которому вы можете привязать в представлении:

<TreeView ItemsSource="{Binding Files.Items}"
          SelectedItemChanged="TreeView_OnSelectedItemChanged" ... />
<DataGrid ItemsSource="{Binding SelectedFile.FileProperties}"
          Visibility="{Binding IsSelectedFileVisible, Converter={StaticResource BoolToVis}}" ... />

И

void TreeView_OnSelectedItemChanged(...)
{
    var vm = (MainWindowViewModel)DataContext;
    vm.SelectedFile = ...
}

Ссылки: 1 , 2 , 3 .

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