我目前正在开发Visual Studio扩展,对C#还是陌生的。我需要具有明显类似于主从模式的东西,但是我需要在2个单独的工具窗口中使用它:
我的问题是:
我发现了很多指南和示例,这些指南和示例在单个XAML文件中的单个视图中显示了主从模式。我永远找不到在2个单独的视图/ XAML文件上能正确显示的内容。
所以我尝试了手动操作:
创建一个单独的“结果列表”工具窗口。单击“结果列表”工具窗口中的按钮时,可以在启动时(通过VS包的Initialize方法)或事件管理中用伪造的硬编码结果填充它。
创建一个单独的“结果详细信息”工具窗口。我可以在启动时或从事件管理中类似地填充伪造数据。但是我无法通过在“结果列表”中选择一行来更新它。
->好像从“外部”调用更新时绑定不起作用。
结果列表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更改,但此后似乎丢失,并且从不更新Result Details UI。好像从“外部”进行更新不起作用。
通过单击按钮调用Update_Button时,DataContext更改已完成,结果详细信息用户界面 已正确更新。好像允许从“内部”进行更新。
任何建议将不胜感激!
答案 0 :(得分:0)
也许您可以添加一个静态中产阶级,其中有一个钥匙(静态 int)。让密钥成为第一个窗口和第二个窗口之间的桥梁,因为很难使第一个窗口直接与第二个窗口交互。
假设您的扩展名类似于带有列表框的窗口和带有文本框的窗口。
在您的FirstWindow.xaml.cs中,在您的单击或选择事件处理程序中添加一个简单的func doGetLocalDataUser() -> logInResponse? {
guard let userData = UserDefaults.standard.data(forKey: ConstantStrings.KEY_USER_LOGIN_DATA), let user = try? JSONDecoder().decode(logInResponse.self ,from: userData) else {
return nil
}
return user
}
。
然后在您的key=xxx;
中,订阅一个密钥更改的事件(使用dispatcherTimer或其他方法)。每次在SecondWindow.xaml.cs
中选择列表框的项目时,都将键变量的值设置为特定值。然后secondToolWindows知道,根据FirstToolWindow
的值进行操作。
我认为必须有一种更好的方法来实现您的目标,但是由于时间原因,我想出了一种更好的方法。无论如何,希望它能有所帮助。