gpt4 book ai didi

c# - 将 DataGridComboBoxColumn 值传递给 ObjectDataProvider 的 MethodParameter

转载 作者:行者123 更新时间:2023-12-03 10:36:31 30 4
gpt4 key购买 nike

我在 DataGrid 中有两个 DataGridComboBoxColumns(技术上是 DataGridTemplateColumns)。我正在使用 MVVM。

第一列的 ItemsSource 绑定(bind)到静态资源——那里没问题。

第二列的 ItemsSource 取决于第一列选择的值。第一列的值 (SelectedValue) 作为 MethodParameter 传递给 ObjectDataProvider。 ObjectDataProvider 是第二列的 ItemsSource。

使用第一列的 SelectedValue 作为 ObjectDataProvider 的 MethodParameter 的问题是当我在 DataGrid 中插入第二行时。如果第二行在第 1 列中使用的值与在第一行的第 1 列中使用的值不同,则会清除第一行的第 2 列值(因为新的 SelectedValue 更改了允许的可供选择的项目列表,由 ObjectDataProvider 提供)。

我真的很想将第一列的 Text 值作为它的 MethodParameter 传递给 ObjectDataProvider,但是当第一列的 Text 值已经绑定(bind)到更新我的模型时,我该怎么做呢?

这是我的问题 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 )。这个 MSDN solution如果这不是 DataGrid,会很好用。

最佳答案

恕我直言,您试图在 XAML 中做太多事情。

你最好利用你的虚拟机。

这是一个模仿您的模型和情况的示例:

业务/虚拟机实体:

public class Product : INotifyPropertyChanged
{
private static readonly IDictionary<string, string[]> catalog = new Dictionary<string, string[]>
{
{ "Fruit", new[]{ "Apple", "Banana", "Cherry" } },
{ "Vegatable", new[]{ "Amaranth", "Broccolini", "Celery" } }
};

public static IDictionary<string, string[]> Catalog { get { return catalog; } }

private string productLineCategoryCode;
public string ProductLineCategoryCode
{
get { return productLineCategoryCode; }
set
{
if (value != productLineCategoryCode)
{
productLineCategoryCode = value;
PropertyChanged(this, new PropertyChangedEventArgs("ProductLineCategoryCode"));
PropertyChanged(this, new PropertyChangedEventArgs("ProductLineCodes"));
}
}
}

public IEnumerable<string> ProductLineCodes
{
get
{
return Catalog[ProductLineCategoryCode];
}
}

private string productLineCode;
public string ProductLineCode
{
get { return productLineCode; }
set
{
if (value != productLineCode)
{
productLineCode = value;
PropertyChanged(this, new PropertyChangedEventArgs("ProductLineCode"));
}
}
}

public event PropertyChangedEventHandler PropertyChanged = delegate { };
}
ProductLineCodes是给定类别的可用代码列表,您只需绑定(bind)到它。

因此,当用户更改类别时,我们会通知它和可用代码列表都已更改。

风景:
<DataGrid ItemsSource="{Binding Products}" CanUserAddRows="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Product Line Cat"
ClipboardContentBinding="{Binding ProductLineCategoryCode}">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox IsEditable="True"
ItemsSource="{Binding Path=(local:Product.Catalog).Keys}"
SelectedValue="{Binding ProductLineCategoryCode, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ProductLineCategoryCode}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Product Line" ClipboardContentBinding="{Binding ProductLineCode}">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox IsEditable="True"
ItemsSource="{Binding ProductLineCodes}"
SelectedValue="{Binding ProductLineCode,UpdateSourceTrigger=PropertyChanged}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding ProductLineCode}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>

我可以想象另一个变体使用 IValueConverter但我希望这个对你的用例来说足够好......

关于c# - 将 DataGridComboBoxColumn 值传递给 ObjectDataProvider 的 MethodParameter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25689630/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com