所以,这是我的场景:我有一个ComboBox
其中itemssource
是各种标题和它们的ID的Dictionary<int, string>
。这些标题可能会在将来的某个时间点被禁用,因此不应再显示在ComboBox
中。但是,在查看旧项目时,除了当前有效的标题之外,我仍然需要显示此旧值。我会尽量想象下面更好一点。添加项目到itemssource,如果没有匹配从绑定
今日:
组合框的项目包括
- 1,标题1
- 2,标题2
- 3,TITLE3
TITLE3被选择,并且ID (3)被存储。
明天:
TITLE3被禁用,并且被添加TITLE4,所以项目现在包括
- 1,标题1
- 2,标题2
- 4,TITLE4
但是,如果我们昨天的价值是我们的价值丁(ID 3),没有匹配的项目。理想情况下,我想我们的老项目追加到尾部,像这样:
- 1,标题1,
- 2,标题2
- 4,TITLE4
- 3,TITLE3
显然会有单独的启用和禁用标题列表,任何未正确绑定的项目都可以引用已禁用的标题变量。
我调查了fallbackValues
甚至PriorityBindings
,但似乎无法找到一种方法使它们适合我所要做的。也许某种转换器与fallbackValue
一起使用?我感谢帮助和反馈。
此外,作为参考,这是我目前正在使用的代码(我正在寻找这样的数据网格)。
WPF:在视图模型
<DataGridTemplateColumn x:Name="tkTitle" Header="Title" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding DataContext.TaskTitles, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}}" SelectedValue="{Binding Path=tkttID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Key" DisplayMemberPath="Value" Width="Auto" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
相关的代码:
public Dictionary<int, string> TaskTitles
{
get
{
return BestClass.taskTitles;
}
}
编辑 - 工作守则 这里是我用来获取一切工作的代码。ItemsSource已更新为带转换器的MultiBinding。 MultiBinding包含活动的TaskTitles,所有的TaskTitles和ID。这些全部都会传递给转换器,以便在活动列表中检查ID,并在未激活时添加。感谢所有人的帮助!
WPF
<DataGridTemplateColumn x:Name="tkTitle" Header="Title" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox SelectedValue="{Binding Path=tkttID, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValuePath="Key" DisplayMemberPath="Value" Width="Auto">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource CheckDisabledTaskTitle}" Mode="OneWay">
<MultiBinding.Bindings>
<Binding Path="DataContext.TaskTitles" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}" />
<Binding Path="DataContext.AllTaskTitles" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGrid}}" />
<Binding Path="tkttID" />
</MultiBinding.Bindings>
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
代码隐藏转炉
class CheckDisabledTaskTitle : IMultiValueConverter
{
//values[0] - Active values
//values[1] - All values (including disabled)
//values[2] - Current ID
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//Check to see if the active values contain our current ID
if (((Dictionary<int, string>)values[0]).ContainsKey((int)values[2]))
{
//They do, so return just the active values
return values[0];
}
else
{
//They don't, so we'll add only our disabled value to the active list
((Dictionary<int, string>)values[0]).Add((int)values[2], ((Dictionary<int, string>)values[1])[((int)values[2])]);
//Then give that back
return values[0];
}
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
我想我已经用你在这里提供的东西取得了一些很好的进展,但我遇到了一个障碍。我试图将tkttID传递给转换器,所以在那里我可以检查它是否被禁用,并相应地添加额外的标题,但是我得到一个异常,将一个绑定添加到ConverterParameter。我可能会以错误的方式来处理这个问题,但希望得到一些指导。 – jmgardn2 2013-04-25 17:54:25
尽可能多的时间-np :) - 你是否将你的转换器实现为“IMultiValueConverter”?它需要一系列的价值 - 只是一点点不同而已。如果它没有帮助,尝试一些并提出一些代码,我会检查并让你知道。 – NSGaga 2013-04-25 18:06:16
我认为这个解决方案有你需要的一切 - 这是一个处理更复杂情况的标准模式,通过更多变量在转换器中“做出选择”(或者传递“this”等) - 你可以用'注释行' - 如果需要则传递整个视图模型) – NSGaga 2013-04-25 18:08:14