0

這是我已經更新到希望運行的問題,是一個更加清楚一點。 總之我試圖做到的是從列表框中所選項目的屬性傳遞給視圖模型,使這個屬性可以在新的查詢中使用。在下面的代碼中,列表框繼承了父對象的數據綁定。列表框包含用於渲染詳細結果的數據模板(用戶控件)。如何將一個列表框的selectedItem屬性傳遞給視圖模型

我遇到的問題是,用戶控件中我點擊它時,調用從視圖模型的命令的擴展。從我所看到的ListBox對象丟失數據上下文,所以爲了在擴展器展開時調用命令,我必須顯式設置擴展器的datacontext。這樣做似乎實例化了一個新的視圖模型,它將我的綁定屬性(SelectedItemsID)重置爲null。

有沒有辦法從視圖傳遞選定項目到視圖模型,並防止被重置當按鈕從模板列表框中項目中調用的命令爲空值?

我意識到,棱鏡和MVVMLite都有這種解決方法,但我不熟悉或者框架,所以我不知道複雜的切割任一到我的項目的水平。

可這棱鏡或MVVMLite之外實現的呢?

原帖如下:

在我的項目,我有一個列表框用戶控件包含自定義數據模板。

<ListBox x:Name="ResultListBox" 
      HorizontalAlignment="Stretch" 
      Background="{x:Null}" 
      BorderThickness="0" 
      HorizontalContentAlignment="Stretch" 
      ItemsSource="{Binding SearchResults[0].Results, 
            Mode=TwoWay}" 
      ScrollViewer.HorizontalScrollBarVisibility="Disabled" 
      SelectionChanged="ResultListBox_SelectionChanged"> 
     <ListBox.ItemTemplate> 

      <DataTemplate> 
       <dts:TypeTemplateSelector Content="{Binding}" HorizontalContentAlignment="Stretch"> 
        <!-- CFS Template --> 
        <dts:TypeTemplateSelector.CFSTemplate> 
         <DataTemplate> 
           <qr:srchCFS /> 
         </DataTemplate> 
        </dts:TypeTemplateSelector.CFSTemplate> 

        <!-- Person Template --> 
        <dts:TypeTemplateSelector.PersonTemplate> 
         <DataTemplate> 
           <qr:srchPerson /> 
         </DataTemplate> 
        </dts:TypeTemplateSelector.PersonTemplate> 

        <!-- removed for brevity --> 

      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 

的SelectionChanged調用從代碼如下方法背後

private void ResultListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (((ListBox)sender).SelectedItem != null) 
     _ViewModel.SelectedItemID = (((ListBox)sender).SelectedItem as QueryResult).ID.ToString(); 
     this.NotifyPropertyChanged(_ViewModel.SelectedItemID);//binds to VM 
    } 

在視圖模型我有以下特性

public string SelectedItemID 
    { 
     get 
     { 
      return this._SelectedItemID; 
     } 
     set 
     { 
      if (this._SelectedItemID == value) 
       return; 
      this._SelectedItemID = value; 
     } 

    } 

列表框模板包含與膨脹的控制自定義佈局。擴展器控件用於顯示與選定項目相關的更多細節。這些細節(集合)是通過對我的代理進行新的呼叫而創建的。與膨脹的控制做到這一點我使用的表達式InvokeCommandAction

<toolkit:Expander Height="auto" 
          Margin="0,0,-2,0" 
          Foreground="#FFFFC21C" 
          Header="View Details" 
          IsExpanded="False" 
          DataContext="{Binding Source={StaticResource SearchViewModelDataSource}}" 
          Style="{StaticResource DetailExpander}"> 

      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="Expanded"> 
        <i:InvokeCommandAction Command="{Binding GetCfsResultCommand}" /> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 

在視圖模型的委託指令GetCFSResultCommandExecute被稱爲是相當直截了當

private void GetCfsResultCommandExecute(object parameter) 
    { 
     long IdResult; 
     if (long.TryParse(SelectedItemID, out IdResult)) 
     { 
      this.CallForServiceResults = this._DataModel.GetCFSResults(IdResult);} 

我遇到選擇列表框時的問題Item的selectionchanged事件觸發,並使用選定項目中的正確ID更新SelectedItemID屬性。當我點擊擴展器時,Command被觸發,但是SelectedItemID屬性被設置爲null。我曾與Silverlight的間諜跟蹤這和事件都與被點擊的擴展,當列表框項目失去焦點,擴展器(切換),你會想到什麼一致得到集中且有LeftMouseDownEvent,但我看不到任何東西發生,這也解釋了爲什麼該屬性被設置爲null。我將選擇已更改的事件中使用的代碼添加到listboxt項目上的LostFocus事件,並且仍然收到相同的結果。

我會很感激與理解爲什麼公共財產SelectedItemID被設置爲空時擴展按鈕,這是ListBox控件的部分被設置爲null任何幫助。當然,我會非常感謝在學習如何防止將該屬性設置爲null並保留綁定ID方面的幫助。

更新 我試圖刪除從擴展DataContext的參考,因爲這建議是問題。從我所擁有的,因爲這是一個數據模板項目,它從可視樹中「跳出」,並且失去對從父對象繼承的控件的datacontext的引用。如果我嘗試在控件的代碼中設置datacontext,則所有對屬性的綁定都會丟失。

我的下一個嘗試是設置在構造函數中的膨脹機控制在DataContext爲

private SearchViewModel _ViewModel; 
    public srchCFS() 
    { 
     InitializeComponent(); 
     this.cfsExpander.DataContext = this._ViewModel; 
    } 

這種做法似乎並沒有工作,因爲InvokeCommandAction永遠不會被解僱。如果在擴展器上設置了數據上下文,該命令似乎只會觸發。

在此先感謝

+0

你amking此* *得多難度比它必須這樣做。只需將SelectedItem綁定回ViewModel並從該項目獲取Id即可。嘗試將SelectedItem綁定到Model的屬性將需要你做大量的提升,因爲ItemsControl期望SelectedItem是其ItemsSrouce屬性內的實例,而不是其中一個實例的*屬性*。 – Will 2011-06-08 14:54:59

+0

@願意,我會嘗試這個,但它似乎並沒有工作SelectedItem =「{Binding SelectedItemID,Mode = TwoWay}」我假設這可能是由於列表框項目是用戶控件組成的屬性集合? – rlcrews 2011-06-08 15:22:15

+0

'SearchResults [0] .Results'是一個X類型的集合。你在ViewModel上公開一個X類型的DP,稱之爲'SelectedX'。然後你將它綁定到'SelectedItem =「{Binding SelectedX}」',這樣當你選擇列表中的某個項目時,該項目就可以在'SelectedX'中找到。然後您可以執行'SelectedX.Id'來獲取該Id。 – Will 2011-06-08 16:18:35

回答

0

儘管這是一種冒險的方法,但我發現了一箇中間解決方案,可以將列表框項目值賦予視圖模型。我最終使用選擇已更改的事件並將值直接傳遞給我的視圖模型中的公共屬性。不是最好的方法,但它解決了這個問題短期內

private void ResultListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     if (((ListBox)sender).SelectedItem != null) 
      _ViewModel.SelectedItemID = (((ListBox)sender).SelectedItem as QueryResult).ID.ToString(); 
      MySelectedValue = (((ListBox)sender).SelectedItem as QueryResult).ID.ToString(); 
     this.NotifyPropertyChanged(_ViewModel.SelectedItemID); 
    } 

對於這個火我也必須設置屬性在視圖中改變處理程序將更改推到VM。您可以忽略MySelectedValue行,因爲它是用於測試的二級代碼。

對於那些intereted通用屬性更改處理器

 public event PropertyChangedEventHandler PropertyChanged; 

    private void NotifyPropertyChanged(string info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 
0

通過此行您將使用它的默認構造新SearchViewModelDataSource。

DataContext="{Binding Source={StaticResource SearchViewModelDataSource}}" 

我想這就是爲什麼你找到null因爲這是引用類型的默認值。 您可以通過將DataContext設置爲用於主控件1的相同實例來解決此問題(可以在初始化所有組件後通過代碼執行此操作)。

希望得到這個幫助!


編輯

我不認爲結合可以從代碼中設置的DataContext後丟失。我每次都需要在兩個或更多模型之間分享內容。
關於代碼你寫:

private SearchViewModel _ViewModel; 
public srchCFS() 
{ 
    InitializeComponent(); 
    this.cfsExpander.DataContext = this._ViewModel; 
} 

而不是使用this.cfsExpander,你可以嘗試使用FindName方法。也許這會使你返回正確的實例。

object item = this.FindName("expander_name"); 
if ((item!=null)&&(item is Expander)) 
{ 
    Expander exp = item as Expander; 
    exp.DataContext = this._ViewModel; 
} 

試試看是否適合你。
當然,this._ViewModel必須公開一個名爲GetCfsResultCommand的ICommand類型的屬性,但我認爲這已經完成了。

+0

LoSciamano,你可以提供一個例子,說明如何在代碼中進行設置initalizes>我已經嘗試過,但我的方法仍然失敗。謝謝 – rlcrews 2011-06-07 17:47:48

+0

由於這是一個自定義列表框模板,它在可視樹之外進行。因此它不會從父對象繼承datacontext。爲了讓命令觸發,好像我必須爲xaml中的擴展器設置datacontenxt。我已更新我的問題以反映所做的更改。 – rlcrews 2011-06-07 17:55:55

+0

編輯答案:希望這可以工作。 – LoSciamano 2011-06-07 18:37:17

相關問題