Передача значения элемента, выбранного в Gridview, в ViewModel другого Usercontrol - PullRequest
3 голосов
/ 27 февраля 2012

После трехдневного поиска решения, я наконец сдался. Теперь мне нужна ваша помощь, чтобы решить эту проблему.

Сценарий:

У меня есть GridView в пользовательском контроле (допустим, WLMSLogs.xaml), а My GridView ItemSource привязан к списку из ViewModel (WMLSLogsViewModel.cs)

Допустим, список состоит из 4 элементов (EventID, Name, Request и Response). И запрос, и ответ - это XML-строки.

GridView должен отображать некоторые элементы списка в RowDetailsTemplate под различными элементами вкладки. Поэтому я отображаю Запрос и Ответ под соответствующими 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

Пока все работает нормально, и Grid отображает данные, как и ожидалось.

Теперь, когда пользователь раскрывает любую строку, он может видеть две TabItems с запросом и ответом. Здесь мне нужно добавить еще один TabItem (LogEvents) помимо вкладок «Запрос» и «Ответ».

Эта вкладка LogEvents будет иметь еще один GridView для отображения (поэтому я добавил новый View <views:LogEvents /> во вкладку). Здесь начинается сложная часть.

Этот LogEvents GridView должен получать данные на основе соответствующего Selecteditem (то есть EventId) и передавать это EventId в другую ViewModel (LogEventViewModel.cs) и динамически связывать данные с Inner GridView. , Все это должно происходить либо при расширении раздела RowDetails, либо при выборе вкладки LogEvents.

Нет никакого отношения между элементами данных этих двух гридов, кроме получения Selected EventId основного GridView и передачи его в другой ViewModel, а затем в службу домена, чтобы получить внутренние данные GridView.

Что я делал до сих пор

Как я уже говорил, я создал новый View UserControl для LogEvents, поместил его в новый TabItem (EventLogs) внутри шаблона сведений о строках основного GridView.

LogEvent UserControl содержит Grid View, связанный с LogEventsViewModel, чтобы получить коллекцию на основе выбранной строки EventId.

Как мне назначить выбранный EventId новой ViewModel и получить данные динамически?

One Way: как я вам показал, я вызвал LogEvents, поместив его в боковой TabItem. всякий раз, когда я раскрываю какую-либо строку, затем она инициализирует страницу LogEvents, во время которой я пытался связать Datacontext с LogEventsViewModel. Но я не могу получить Выбранный ряд 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 ]

7 голосов
/ 27 февраля 2012

Я бы создал свойство зависимости в вашей 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 голос
/ 30 января 2013

KodeKreachor верен, хотя может потребоваться установить атрибут Bindable для вашего открытого свойства.Без него свойство может не всегда отображаться в привязываемых свойствах элемента управления, даже если оно все еще работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...