這是我已經更新到希望運行的問題,是一個更加清楚一點。 總之我試圖做到的是從列表框中所選項目的屬性傳遞給視圖模型,使這個屬性可以在新的查詢中使用。在下面的代碼中,列表框繼承了父對象的數據綁定。列表框包含用於渲染詳細結果的數據模板(用戶控件)。如何將一個列表框的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永遠不會被解僱。如果在擴展器上設置了數據上下文,該命令似乎只會觸發。
在此先感謝
你amking此* *得多難度比它必須這樣做。只需將SelectedItem綁定回ViewModel並從該項目獲取Id即可。嘗試將SelectedItem綁定到Model的屬性將需要你做大量的提升,因爲ItemsControl期望SelectedItem是其ItemsSrouce屬性內的實例,而不是其中一個實例的*屬性*。 – Will 2011-06-08 14:54:59
@願意,我會嘗試這個,但它似乎並沒有工作SelectedItem =「{Binding SelectedItemID,Mode = TwoWay}」我假設這可能是由於列表框項目是用戶控件組成的屬性集合? – rlcrews 2011-06-08 15:22:15
'SearchResults [0] .Results'是一個X類型的集合。你在ViewModel上公開一個X類型的DP,稱之爲'SelectedX'。然後你將它綁定到'SelectedItem =「{Binding SelectedX}」',這樣當你選擇列表中的某個項目時,該項目就可以在'SelectedX'中找到。然後您可以執行'SelectedX.Id'來獲取該Id。 – Will 2011-06-08 16:18:35