将Gridview中选定项目的值传递给另一个Usercontrol的ViewModel

rav*_*lla 3 silverlight silverlight-4.0

经过三天研究解决方案后,我终于放弃了.现在我需要你的帮助来解决这个问题.

场景:

我在Usercontrol中有一个GridView(比如说WLMSLogs.xaml),我的GridView ItemSource被绑定到ViewModel的一个List(WMLSLogsViewModel.cs)

让我们说List有4个项目(EventID,Name,Request和Response).BothRequest和Responses都是XML字符串.

GridView需要在不同的选项卡项下显示RowDetailsTemplate中的一些List项.所以我在各自的TabItem下显示请求和响应.

<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>
Run Code Online (Sandbox Code Playgroud)

WMLSLogModelList是WMLSLogsViewModel.cs中的Observable集合

到目前为止一切正常,Grid正在按预期显示数据.

现在,当用户展开任何行时,他可以看到两个包含请求和响应的TabItem.在这里,除了请求和响应选项卡之外,我还需要添加一个TabItem(LogEvents).

此LogEvents选项卡将再显示一个GridView(因此我<views:LogEvents />在选项卡中添加了一个新视图).这是棘手的部分.

此LogEvents GridView需要根据相应的Selecteditem(即EventId)获取数据,并将其传递EventId给不同的ViewModel(LogEventViewModel.cs)并将数据动态绑定到Inner GridView.所有这些都必须在我展开RowDetails部分或我选择Tab LogEvents时发生.

这两个网格的数据项之间没有关系,除了获取主GridView的Selected EventId并将其传递给另一个ViewModel然后传递给Domain服务以获取内部GridView数据.

到目前为止我做了什么

正如我所提到的,我为LogEvents创建了一个新的View UserControl,将它放在主GridView的行详细信息模板中的新TabItem(EventLogs)下.

LogEvent UserControl包含一个绑定到LogEventsViewModel的网格视图,以根据Selected行EventId获取Collection.

如何将Selected EventId分配给新的ViewModel并动态获取数据?

单向:正如我向您展示的那样,我通过将其置于侧面TabItem中来调用LogEvents.每当我展开任何行,然后它正在初始化LogEvents页面,在此期间我尝试将Datacontext绑定到LogEventsViewModel.但我无法动态获取Seleted行EventId.如果我得到了那么我可以很容易地将它传递给LogEventsViewModel构造函数.

       var _viewModel = new LogEventsViewModel(EventId);
       this.DataContext = _viewModel;            
       InitializeComponent();
Run Code Online (Sandbox Code Playgroud)

其他方法:将所选的EventId直接从xaml View绑定传递到该页面初始化,然后传递给LogEventsViewModel这样的东西

<views:LogEvents  something="{Binding EventId}"/>
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以做到这一点?

细节:

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>
Run Code Online (Sandbox Code Playgroud)

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 
    }
Run Code Online (Sandbox Code Playgroud)

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;}
    }
Run Code Online (Sandbox Code Playgroud)

Kod*_*hor 7

我会在你的LogEventsViewModel上创建一个依赖属性,然后在你的LogEvents视图上设置一个绑定,如下所示:

<views:LogEvents EventId="{Binding EventId}" />
Run Code Online (Sandbox Code Playgroud)

然后在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;
    }
Run Code Online (Sandbox Code Playgroud)