在研究了三天的解决方案后,我最终放弃了。现在,我需要您的帮助来解决此问题。
场景:
我在用户控件中有一个GridView(比如说WLMSLogs.xaml),并且我的GridView ItemSource已绑定到ViewModel的列表(WMLSLogsViewModel.cs)
可以说列表有4个项目(EventID,名称,请求和响应)。 Request和Response都是XML字符串。
GridView需要在RowDetailsTemplate中的不同选项卡项下显示一些List项。所以我在各自的TabItems下显示Request和Response。
<GridView x:Name="WMLSLogGrid" ItemsSource="{Binding WMLSLogModelList}">
<GridView.Columns>
<GridViewDataColumn DataMemberBinding="{Binding ID}" Header="ID"/>
<GridViewDataColumn DataMemberBinding="{Binding UserName}" Header="UserName"/>
</GridView.Columns>
<GridView.RowDetailsTemplate>
<DataTemplate >
<TabControl>
<TabItem Header="Request Xml">
<TextBlock text="{Binding Request}"/>
</TabItem>
<TabItem Header="Response Xml">
<TextBlock text="{Binding Response}"/>
</TabItem>
<TabItem Header="EventLogs" Tag="{Binding .}">
<views:LogEvents />
</TabItem>
</TabControl>
</Grid>
</DataTemplate>
</GridView.RowDetailsTemplate>
WMLSLogModelList是WMLSLogsViewModel.cs中的Observable集合
到目前为止,一切正常,并且Grid正在按预期显示数据。
现在,当用户展开任何行时,他可以看到两个带有请求和响应的TabItem。
在这里,除了“请求”和“响应”选项卡之外,我还需要添加一个TabItem(LogEvents)。
这个LogEvents标签将再显示一个GridView(所以我在标签中添加了一个新的View
<views:LogEvents />
)。棘手的部分到了。此LogEvents GridView需要基于相应的
Selecteditem
(即EventId
)获取数据,并将此EventId
传递给另一个ViewModel(LogEventViewModel.cs),然后将数据动态绑定到内部GridView。当我展开RowDetails部分或选择Tab LogEvents时,所有这些都必须发生。除了获取主GridView的Selected EventId并将其传递给其他ViewModel然后传递给Domain服务以获取内部GridView数据外,这两个Grid的数据项之间没有关系。
我到目前为止所做的
正如我提到的,我为LogEvents创建了一个新的View UserControl,将其放在主GridView的行详细信息模板内的新TabItem(EventLogs)下。
LogEvent UserControl包含一个绑定到LogEventsViewModel的网格视图,以根据“选定的行” EventId获取集合。
如何将Selected EventId分配给新的ViewModel并动态获取数据?
一种方式:正如我向您展示的那样,我将LogEvents放置在TabItem侧面。每当我扩展任何行,然后它就会初始化LogEvents页面,在此期间,我尝试将Datacontext绑定到LogEventsViewModel。但是我无法动态获取Seleted行的EventId。如果我明白了,那么我可以轻松地将其传递给LogEventsViewModel构造函数。
var _viewModel = new LogEventsViewModel(EventId);
this.DataContext = _viewModel;
InitializeComponent();
另一种方式:
直接从xaml View绑定中将选定的EventId传递给该页面初始化,然后传递给LogEventsViewModel
像这样
<views:LogEvents something="{Binding EventId}"/>
还有其他方法吗?
细节:
LogEvents.xaml
<UserControl.Resources>
<viewModel:LogEventsViewModel x:Key="ViewModel"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource ViewModel}}">
<GridView x:Name="LogEventsGrid" ItemsSource="{Binding View}"
<GridView.Columns>
<telerik:GridViewToggleRowDetailsColumn />
<telerik:GridViewDataColumn DataMemberBinding="{Binding EventId}" Header="LogEventId"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Exception}" Header="Exception" />
</GridView.Columns>
</telerik:RadGridView>
</Grid>
LogEvents.xaml.cs
public int EventId
{
get { return (int)GetValue(EventIdProperty); }
set { SetValue(EventIdProperty, value); }
}
public static readonly DependencyProperty EventIdProperty =
DependencyProperty.Register("EventId", typeof(int), typeof(ApplicationLog),
new PropertyMetadata(0, new PropertyChangedCallback(OnEventIdChanged)));
private static void OnEventIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
int LogEventId1 = (int)e.NewValue;
// Need to assign propery in LogEventsViewModel
}
LogEventsViewModel.cs
WMLCDomainContext _Context = new WMLCDomainContext();
private QueryableDomainServiceCollectionView<LogEvents> view;
public int _eventid;
public ApplicationLogsViewModel()
{
EntityQuery<LogEvents> getLogEventsQuery = _Context.GetApplicationLogListQuery(EventId);
this.view = new QueryableDomainServiceCollectionView<ApplicationLog>(_Context, getLogEventsQuery );
}
public IEnumerable View
{get {return this.view;}}
public int EventId
{
get{return this._eventid;}
set{_eventid = value;}
}
最佳答案
我会在LogEventsViewModel上创建一个依赖项属性,然后在LogEvents视图上设置绑定,如下所示:
<views:LogEvents EventId="{Binding EventId}" />
然后,可以在LogEvents.xaml.cs中创建依赖项属性:
private LogEvents_ViewModel _viewModel
{
get { return this.DataContext as LogEvents_ViewModel; }
}
public string EventId
{
get { return (string)GetValue(EventIdProperty); }
set { SetValue(EventIdProperty, value); }
}
public static readonly DependencyProperty EventIdProperty =
DependencyProperty.Register("EventId", typeof(string), typeof(LogEvents),
new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnEventIdChanged)));
private static void OnEventIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((LogEvents)d).OnTrackerInstanceChanged(e);
}
protected virtual void OnEventIdChanged(DependencyPropertyChangedEventArgs e)
{
this._viewModel.EventId = e.NewValue;
}