2013-04-25 57 views
1

所以,这是我的场景:我有一个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(); 
    } 
} 

回答

1

如果我知道你在这里后在做什么......

1)我相信你应该修改的东西在您的视图模型 - 并提供一个default,如果结果为空或空(你需要实现您的INotifyPropertyChanged以通知更改等)。

2)另一种选择将是某种形式的转换器的 - 这需要你的列表属性,并使用MultiBinding

详见这个帖子我的(主要是有代码) - refreshing Value Converter on INotifyPropertyChanged

基本上你地结合你的财产清单 - 和“默认列表” - 和你的转换器里面,您可以做决定做什么。

例如为:

<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> 
+0

我想我已经用你在这里提供的东西取得了一些很好的进展,但我遇到了一个障碍。我试图将tkttID传递给转换器,所以在那里我可以检查它是否被禁用,并相应地添加额外的标题,但是我得到一个异常,将一个绑定添加到ConverterParameter。我可能会以错误的方式来处理这个问题,但希望得到一些指导。 – jmgardn2 2013-04-25 17:54:25

+0

尽可能多的时间-np :) - 你是否将你的转换器实现为“IMultiValueConverter”?它需要一系列的价值 - 只是一点点不同而已。如果它没有帮助,尝试一些并提出一些代码,我会检查并让你知道。 – NSGaga 2013-04-25 18:06:16

+1

我认为这个解决方案有你需要的一切 - 这是一个处理更复杂情况的标准模式,通过更多变量在转换器中“做出选择”(或者传递“this”等) - 你可以用'注释行' - 如果需要则传递整个视图模型) – NSGaga 2013-04-25 18:08:14

0

我想你需要修改集合中的视图模型,使你...

  1. 加载允许值(TaskTitles)
  2. 检查允许值中的选定值(tkttID)。如果它不存在,则添加它。

要做到这一点,你应该给TaskTitles与二传手的汽车性能,让您可以在其他地方管理的内容..

e.g ......(下面未经测试,因为我没有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,所以这集将不受影响。您正在创建一个新的集合并添加相同的值,以及(可能)另一个值。

+0

你能否详细说明与二传手汽车财产?不是很熟。谢谢! – jmgardn2 2013-04-25 17:12:24

+0

自动属性只是一个属性,而不支持字段.... 公共字符串myProperty的{获取;集;} (在你的榜样你“撑腰场”是BestClass.TaskTitles)..在“{获得;设置;}“部分是什么使它成为一个自动属性 ...和一个setter我的意思是”集合;“位 - 这意味着您可以在代码中的其他位置设置属性...即属性为可写 – 2013-04-25 17:40:31

+0

ps.s.它不一定是一个自动属性,它看起来比替代更好......见http:// stackoverflow。com/questions/9304/c-sharp-3-0-auto-properties-useful-or-not – 2013-04-25 17:46:38

相关问题