所以,这是我的方案:我有一个ComboBox
,其中itemssource
是各种标题及其ID的Dictionary<int, string>
。这些标题可以在将来的某个时候禁用,因此不应再显示在ComboBox
中。但是,在查看旧项目时,我仍然需要能够显示除当前活动标题之外的旧值。我会尝试在下面稍微想象一下。
今天:
ComboBox项目由
组成选择Title3并存储ID(3)。
明天:
Title3已禁用且Title4已添加,因此项目现在包含
但是,如果我们昨天的值是我们绑定的值(ID 3),则没有匹配项。理想情况下,我想将我们的旧项目添加到最后:
显然有启用和禁用标题的单独列表,任何未正确绑定的项目都可以引用禁用的标题变量。
我调查了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>
ViewModel中的相关代码:
public Dictionary<int, string> TaskTitles
{
get
{
return BestClass.taskTitles;
}
}
编辑 - 工作代码 这是我用来使一切工作的代码。 ItemsSource已更新为带转换器的MultiBinding。 MultiBinding包含Active TaskTitles,All TaskTitles和ID。这些全部传递给转换器,因此在活动列表中检查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();
}
}
答案 0 :(得分:2)
如果我明白你在这之后会发生什么......
1)我认为您应该修改视图模型中的内容 - 如果结果为null或为空,则提供default
(您需要实现INotifyPropertyChanged以通知更改那里等)。
2)另一种选择是某种转换器 - 它会获取您的list属性并使用MultiBinding
。
有关详细信息,请参阅我的这篇文章(主要是那里的代码) - refreshing Value Converter on INotifyPropertyChanged
基本上,您绑定了适当的属性列表 - 以及&#39;默认列表&#39; - 在转换器内部,您可以决定做什么。
例如:
<ComboBox ...>
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource ImageConverter}" Mode="OneWay">
<MultiBinding.Bindings>
<Binding Path="TaskTitles" />
<Binding Path="FallbackTitles" />
<!--Binding Path="" /-->
</MultiBinding.Bindings>
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
答案 1 :(得分:0)
我认为您需要在ViewModel中修改您的集合,以便您......
为此,您应该为TaskTitles提供一个带有setter的auto属性,以便您可以在其他地方管理其内容。
例如...(由于我没有VS atm而未经测试)。我也在下面使用过Linq 我认为.NET 3及以上版本。
public Dictionary<int, string> TaskTitles {get;set;}
public void Initialise()
{
TaskTitles = new Dictionary<int, string>();
foreach(var taskTitle in BestClass.taskTitles)
TaskTitles.Add(taskTitle);
if(!TaskTitles.Any(t => t.Value == tkttid.Value))
TaskTitles.Add(tkttid);
}
请注意,您没有添加到BestClass.taskTitles,因此此集合将不受影响。您正在创建一个新集合并添加相同的值,加上(可能)另一个值。