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

时间:2012-02-27 16:54:29

标签: 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项。所以我在相应的TabItems下显示请求和响应。

<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需要根据相应的SelecteditemEventId)获取数据,并将此EventId传递给其他ViewModel(LogEventViewModel.cs)并绑定数据到内部GridView动态。所有这些都必须在我展开RowDetails部分或选择Tab LogEvents时发生。

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

到目前为止我做了什么

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

LogEvent UserControl包含绑定到LogEventsViewModel的网格视图,以根据选定的行EventId获取集合。

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

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

       var _viewModel = new LogEventsViewModel(EventId);
       this.DataContext = _viewModel;            
       InitializeComponent();

其他方式: 将选定的EventId直接从xaml View绑定传递到该页面初始化,然后传递给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;}
    }

2 个答案:

答案 0 :(得分:7)

我会在你的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;
    }

答案 1 :(得分:1)

KodeKreachor是正确的,但可能需要在您的公开属性上设置Bindable属性。没有它,属性可能并不总是显示在控件的可绑定属性中,即使它仍然有效。