使用WPF DataGridComboBoxColumn的IsSynchronizedWithCurrentItem属性

4
我正在尝试在WPF中实现以下场景。
我有一个数据网格,用于显示和添加数据。这是一个新应用程序,但存在旧数据。
过去的一个特定字段随机输入了数据。现在我们想将该字段的值限制为特定列表。因此,我正在使用DataGridComboBoxColumn。顺便说一下,我曾尝试过使用包含ComboBox的DataGridTemplateColumn来解决此问题。
在运行时,如果现有值不在列表中,我希望它仍然显示。但我似乎无法做到这一点。虽然我尝试了各种解决方案(全部失败),但以下解决方案最合乎逻辑。
下拉列表中的值列表在名为“months”的Windows资源中定义。
<DataGridComboBoxColumn x:Name="frequencyCombo"   MinWidth="100" Header="Frequency"
   ItemsSource="{Binding Source={StaticResource months}}"
   SelectedValueBinding="{Binding Path=Frequency,UpdateSourceTrigger=PropertyChanged}">
   <DataGridComboBoxColumn.ElementStyle>
     <Style TargetType="ComboBox">
       <Setter Property="IsSynchronizedWithCurrentItem" Value="False" />
     </Style>
   </DataGridComboBoxColumn.ElementStyle>
</DataGridComboBoxColumn>

发生的情况是,如果一个值不在列表中,则显示为空白。我已经在运行时验证了IsSynchronizedWithCurrentItem元素确实为False。它只是没有做我期望的事情。
也许我走错了路。也许我需要结合使用文本框和组合框。也许我需要编写一些代码,而不仅仅是XAML。我花了几个小时尝试不同的方法,真的很感激有一个解决方案。我已经收到了一些建议,要使用这个类或那个控件,但没有解释如何使用它们。
非常感谢!
5个回答

5
我终于解决了这个问题。诀窍是摆脱comboboxcolumn,使用一个模板,其中包含一个用于显示的文本框和一个用于编辑的组合框。然而,我仍然花了几个小时解决新问题......当在组合框中进行选择时,它会修改任何其他在网格中也使用了组合框的行。猜猜是什么解决了这个问题!就是我之前尝试使用的IsSynchronizedWithCurrentItem属性。 :)
 <DataGridTemplateColumn x:Name="frequencyCombo" Header="Frequency">
   <DataGridTemplateColumn.CellTemplate>
     <DataTemplate>
       <TextBlock Text="{Binding Path=Frequency}" />
     </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
   <DataGridTemplateColumn.CellEditingTemplate>
   <DataTemplate>
     <ComboBox 
       ItemsSource="{Binding Source={StaticResource frequencyViewSource},
       TargetNullValue=''}"
       SelectedItem="{Binding Path=Frequency}" IsSynchronizedWithCurrentItem="False"
      />
    </DataTemplate>
  </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

没有丑陋的hack。没有在下拉菜单底部挂着无用的选项。没有添加额外值并清理它们的代码。
我不会删除Mark建议中的“答案”,因为它使我能够将应用程序交到客户手中,但这就是我正在寻找的解决方案。经过数小时的网络搜索,我在“connect”项目中找到了它的解决方法。
感谢大家的帮助!

你的 frequencyViewSource 代码是什么样子的?我也在尝试做类似的事情。我有一个对象列表中的 List,我想在组合框中显示它,但我无法让 ItemsSource="{Binding Source={StaticResource frequencyViewSource}, TargetNullValue=''}" 这一部分对我起作用。 - user1977591

0
为什么不直接这样做呢:

//create collection
PagedCollectionView view = new PagedCollectionView(e.Result);
view.SortDescriptions.Add(
new SortDescription("Months", ListSortDirection.Ascending));
gridProducts.ItemsSource = view;

//filter collection by category
PagedCollectionView view = new PagedCollectionView(e.Result);
view.Filter = delegate(object filterObject)
{
    Product product = (Product)filterObject;
    return (product.CategoryName == "Legacy");
};
gridProducts.ItemsSource = view;

//create categories through grouping
PagedCollectionView view = new PagedCollectionView(e.Result);
view.GroupDescriptions.Add(new PropertyGroupDescription("Legacy"));
view.GroupDescriptions.Add(new PropertyGroupDescription("etc..."));
gridProducts.ItemsSource = view;

0

试试这个:

    <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox ItemsSource="{Binding Months}"
                                  Text="{Binding Value}"
                                  IsEditable="True" />

                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

<ComboBox ItemsSource="{Binding Source={StaticResource frequencyViewSource}}" Text="{Binding Path=Frequency}" IsEditable="True" />使用此代码,每一行都会显示相同的组合框值(第一行的值)。如果我编辑其中一个,它们都会更改为新值。我将尝试不同的变化。 - Julie Lerman

0

请问您能否澄清这里发生了什么?在运行时,“现有值”是什么并不清楚 - 如果这是数据被随机输入的字段,通过限制它是否意味着您正在运行某种验证逻辑,但仍希望它显示出来?

此外,我更多地关注Silverlight方面...WPF是否也默认为单向绑定?


抱歉,我没有收到电子邮件通知。 :(列表将包括“1个月”、“2个月”、“3个月”等。旧数据可能会有“3个月”。在这种情况下,我仍然希望显示“3个月”。这只是字符串……没有ID、没有哈希表等。我们只是想通过提供一个下拉列表来简化数据输入,并且该下拉列表将恰好具有有限的选项列表。然后,我们就不需要任何验证逻辑等。明白吗?所以我正在与组合框作斗争,因为它只想显示其项目列表中存在的值。 - Julie Lerman

0
与其将静态资源和视图模型属性混合作为列表项的源,您是否尝试在视图模型中使用ObservableCollection或CollectionViewSource?然后,您可以随意插入和删除非标准项,并在需要时使它们被选中(或不选)。因此,“正常”的列表将具有正常的月份,但当出现奇怪的月份时,将其添加到列表中并使其被选中。看起来在视图模型中独立控制会更容易。

我不想将非标准项插入到组合框的项目列表中。但也许我没有理解你的意思。我只是想覆盖组合框文本框中的内容。使用WPF的组合设计,我希望能够访问文本框。但是...我也在想,我是否误解了issynchronizedwithcurrentitem?我知道当我使用窗口中的其他元素作为数据源时,我已经使用过它。谢谢。 - Julie Lerman
我最终走上了这条路,是出于绝望。它感觉非常的hacky,但我已经浪费了一整天的时间,试图想出一个优雅的解决方案,而我无法向客户收取费用。我根据需要向ObservableCollection添加额外的值,然后在下一次填充网格时将它们清除。我不喜欢坏值在下拉列表中可见并且可以被选择。这很丑陋。我将不得不添加更多代码来使它们在用户下拉列表时不可见。谢谢你给了我一个可以使用的想法。 - Julie Lerman
说实话,一直在尝试使用EventSetter修改下拉事件中遗留项目的可见性。但是DropDown并不是路由事件,所以这是行不通的。需要采用另一种方法。我真的不喜欢把旧值塞进列表里,虽然这是个聪明的想法。再次感谢。 - Julie Lerman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接