我在DataGrid中有兩個DataGridComboBoxColumns(技術上DataGridTemplateColumns)。我正在使用MVVM。將DataGridComboBoxColumn值傳遞給ObjectDataProvider的MethodParameter
第一列的ItemsSource綁定到一個靜態資源 - 沒有問題。
第二列的ItemsSource依賴於第一列選擇的值。第一列的值(SelectedValue)作爲MethodParameter傳遞給ObjectDataProvider。 ObjectDataProvider是第二列的ItemsSource。
使用第一列的SelectedValue作爲ObjectDataProvider的MethodParameter的問題是當我在DataGrid中插入第二行時。如果第二行在第一列中使用的值與第一行第一列中的值不同,它將清除第一行的第二列值(因爲新的SelectedValue會更改ObjectDataProvider提供的可供選擇的項目列表)。
我真的很想將第一列的Text值作爲其MethodParameter傳遞給ObjectDataProvider,但是如何在第一列的Text值已經綁定到更新我的模型時這樣做?
這裏是我的問題XAML的摘錄:
<!--
My ObjectDataProvider. It returns a collection of strings for the user to choose from via the second DataGridTemplateColumn.
The first DataGridTemplateColumn feeds ObjectDataProvider a MethodParameter.
The method is simple. It looks like:
public List<String> ProductLineCategoryList_CategoryCodes(string productLineCode)
{
// return a list of strings based from an object collection, filtered by the passed in argument.
}
-->
<ObjectDataProvider x:Key="categoryCodes" ObjectType="{x:Type e:ItemsProvider}" MethodName="ProductLineCategoryList_CategoryCodes">
<ObjectDataProvider.MethodParameters>
<x:StaticExtension Member="sys:String.Empty"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<!--
This DataGridComboBoxColumn lets the user choose a ProductLineCode.
Its SelectedValue provides a string value for the ObjectDataProvider's MethodParameter.
The ObjectDataProvider is used as the ItemsSource for the DataGridComboBoxColumn
below this one.
The problem with using SelectedValue to feed ObjectDataProvider a MethodParameter, when
a second row is added to my DataGrid and the second row uses a different ProductLineCode than
the first row, it clears the first row's ProductLineCategoryCode value.
-->
<DataGridTemplateColumn
Header="Product Line"
ClipboardContentBinding="{Binding ProductLineCode}">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
IsEditable="True"
ItemsSource="{x:Static e:ItemsProvider.ProductLineCategoryList_ProductLineCodeList}"
SelectedValue="{Binding Source={StaticResource categoryCodes},
Path=MethodParameters[0], BindsDirectlyToSource=True,
UpdateSourceTrigger=PropertyChanged}"
Text="{Binding ProductLineCode, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ProductLineCode}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<!--
This DataGridComboBoxColumn uses the ObjectDataProvider for its ItemsSource.
ItemsSource s/b limited by the selection made from the above DataGridComboBoxColumn.
-->
<DataGridTemplateColumn
Header="Product Line Cat"
ClipboardContentBinding="{Binding ProductLineCategoryCode}">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
IsEditable="True"
ItemsSource="{Binding Source={StaticResource categoryCodes}}"
Text="{Binding ProductLineCategoryCode, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ProductLineCategoryCode}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
我所引用的網求救,但我無法找到適合我的解決方案。我只需要傳入一個字符串,而不是一個對象(儘管我想我可以改變我的ObjectDataProvider的方法來接受一個對象並且then this might work)。如果這不是DataGrid,這個MSDN solution會很好用。
這工作。謝謝@Pragmateek!我正在努力保持數據訪問代碼不在我的模型中。現在我明白如果我想這樣做,我需要將每個模型包裝在提供數據訪問邏輯的VM中。現在,我只需根據您的建議將公共字符串[] ProductLineCategoryCodes屬性插入到我的模型中。我稍後將重構(創建更多的虛擬機,然後將其展示給我的View的主虛擬機),以從我的模型中提取數據訪問代碼。謝謝你讓我走出窘境! BTW,很好的配置文件。我會在兩節課學習編程,但我正忙於逆向工程時間。 – 2014-09-08 14:57:19
@DavidAlanCondit很好用。是的,虛擬機在那裏可以調整你的模型,從視圖中緩解消耗。您不必將所有內容都包含在虛擬機中,並且找到合適的平衡點是WPF設計的一些難點,但您做得越多,所需時間就越少。 – Pragmateek 2014-09-08 19:03:10
同意。我做了一個小的重構:我有一個靜態的「ItemsProvider」類,它爲我的許多模型(產品,位置,分區,ProductLineCategories等)加載了列表屬性 - 它將這些列表從數據庫中填充。需要這些列表的模型查詢ItemsProvider,而不是查詢數據庫本身。這可能不是完美的,但它直接是右邊的一步。任何感興趣的人都可以參與 – 2014-09-08 19:12:19