Как реализовать шаблон master-detail на 2 отдельных окнах инструментов? - PullRequest
1 голос
/ 18 апреля 2019

Я в настоящее время разрабатываю расширение Visual Studio и я новичок в C #.Мне нужно иметь что-то, что явно похоже на шаблон основной детали, но мне нужно это в 2 отдельных окнах инструментов:

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

Мои проблемы:

  • Я нашел несколько руководств и примеров, показывающих шаблон основной детали с одним представлением в одном файле XAML.Я никогда не мог найти что-либо, показывающее это должным образом в 2 отдельных файлах представлений / XAML.

  • Поэтому я попытался сделать это вручную:

    • Создатьотдельное окно «Список результатов».Я могу заполнить его поддельными жестко запрограммированными результатами при запуске (из метода инициализации пакета VS) или из управления событиями, нажав кнопку в окне «Список результатов».

    • Создайте отдельное окно «Сведения о результате».Я могу заполнить его поддельными данными при запуске или из управления событиями аналогичным образом.Но я не могу обновить его, выбрав строку в «Списке результатов».

-> Как будто привязка не работаетпри вызове обновления извне.

Список результатов XAML:

<UserControl ... Name="ResultsListToolWindow">
    <StackPanel>
        <ToolBar>
            <Button Click="Update_Button">Update List</Button>
        </ToolBar>
        <ScrollViewer ...>
            <DataGrid SelectionMode="Single"
                Name="ResultsListGrid" 
                ItemsSource="{Binding}" 
                SelectedItem="{Binding SelectedItem}"
                SelectionChanged="SelectionChanged"
                IsSynchronizedWithCurrentItem="True" ...>
                ...
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Family" Binding="{Binding Family}"/>
                    <DataGridTextColumn Header="Type" Binding="{Binding Type}"/>
                    <DataGridTextColumn Header="Check" Binding="{Binding Check}"/>
                </DataGrid.Columns>
            </DataGrid>
        </ScrollViewer>
    </StackPanel>
</UserControl>

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

    public partial class ResultsListToolWindowControl : UserControl
    {
        public ResultsListToolWindowControl()
        {
            InitializeComponent();

            DataContext = Data.ResultsList.GetResultsList();
            // Gets an empty Results List
            // ResultsList is an ObservableCollection<Result>
        }

        private void SelectionChanged(
            object sender, SelectionChangedEventArgs e)
        {
            ResultDetailsToolWindow resultDetailsToolWindow = 
                ResultDetailsToolWindow.GetToolWindow();

            resultDetailsToolWindow.UpdateResultDetails(
                ResultsListGrid.SelectedItem as Data.Result); 
            // Some glue is behind to forward to resultDetailsToolWindowControl
        }

        private void Update_Button(object sender, RoutedEventArgs e)
        {
            Data.ResultsList resultsList = 
                (DataContext as Data.ResultsList);
            resultsList.Update(); // Get some hard-coded results list
        }
    }

Сведения о результате XAML:

<UserControl ... Name="ResultDetailsToolWindow">
    <Grid Name="ResultDetailsGrid">
        <StackPanel Orientation="Vertical">
            <ToolBar>
                <Button Click="Update_Button">
                    Update Details
                </Button>
            </ToolBar>
            <TextBlock Text="{Binding Finding.Family}"/>
            <TextBlock Text="{Binding Finding.Type}"/>
            <TextBlock Text="{Binding Finding.Check}"/>
        </StackPanel>
    </Grid>
</UserControl>

Код сведений о результатах:

    public partial class ResultDetailsToolWindowControl : UserControl
    {
        private class SelectedResult: INotifyPropertyChanged
        {
            private Data.Result result;
            public event PropertyChangedEventHandler PropertyChanged;

            private void NotifyPropertyChanged(
                [CallerMemberName] string propertyName = "")
            {
                PropertyChanged?.Invoke(
                    this, new PropertyChangedEventArgs(propertyName));
            }

            public Data.Result Result
            {
                get { return result; }
                set
                {
                    if (result!= value)
                    {
                        result= value;
                        NotifyPropertyChanged();
                    }
                }
            }

            public SelectedResult() { }
        }

        public ResultDetailsToolWindowControl()
        {
            InitializeComponent();

            ResultDetailsGrid.DataContext = new SelectedResult();
        }

        public void UpdateResultDetails(Data.Result selectedResult)
        {
            if (selectedResult != null)
            {
                (ResultDetailsGrid.DataContext as SelectedResult).Finding = selectedResult; 
            }
        }

        private void Update_Button(object sender, RoutedEventArgs e)
        {
            (ResultDetailsGrid.DataContext as SelectedFinding).Finding = new Data.Result()
            {
                Family = "Defect",
                Type = "Defects",
                Check = "Base class assignment operator not called",
            }; 
        }
    }
}

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

При вызове кнопки Update_Button от нажатия кнопки выполняется изменение DataContext, и пользовательский интерфейс Result Details UI правильно обновляется .Как будто обновление из «изнутри» было разрешено.

Любой совет будет принят с благодарностью!

1 Ответ

0 голосов
/ 25 апреля 2019

Может быть, вы можете добавить статический средний класс, в котором есть ключ (статический целое). Пусть ключ станет мостом между первым окном и вторым, поскольку трудно заставить первое взаимодействовать напрямую со вторым.

Предполагается, что ваше расширение будет чем-то вроде окна со списком и окном с текстовым полем.

В вашем FirstWindow.xaml.cs добавьте простой key=xxx; в свой клик или выберите обработчик события.

Затем в вашем SecondWindow.xaml.cs подпишитесь на событие с измененным ключом (используя dispatcherTimer или что). Каждый раз, когда вы выбираете элемент списка в FirstToolWindow, вы устанавливаете значение ключевой переменной определенное значение. И тогда secondToolWindows знает, что делать в соответствии со значением key.

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

...