【问题标题】:How can I dynamically change the converter on DataGridTextColumn binding in WPF?如何在 WPF 中动态更改 DataGridTextColumn 绑定上的转换器?
【发布时间】:2014-04-16 19:53:34
【问题描述】:

我真的不懂 WPF 和 XAML,并且继承了一些写得非常糟糕的代码,所以我可能会扼杀这个,但这里是。

我继承了一个绑定到 Person 对象列表的 DataGrid(在后面的代码中),其中必要的 DataGridTextColumns 在 XAML 中指定(可能是为了允许样式设置)。

<DataGrid x:Name="PersonGrid" ItemsSource="{Binding}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=LastName}" MaxWidth="Infinity" MinWidth="150" Header="Last Name">
        <DataGridTextColumn Binding="{Binding Path=FirstName}" MaxWidth="Infinity" MinWidth="150" Header="First Name" />
        <DataGridTextColumn Binding="{Binding Path=DOB, StringFormat=\{0:MM/dd/yyyy\}}" MaxWidth="Infinity" MinWidth="200" Header="Date of Birth (MM/DD/YYYY)" />
        <DataGridTextColumn Binding="{Binding Path=Number}" MaxWidth="Infinity" MinWidth="150" Header="(P)erson Number" />
    </DataGrid.Columns>
    <DataGrid.DataContext>
        <dm:Person />
    </DataGrid.DataContext>
</DataGrid>

我想仅显示此人的最后一个姓名首字母,可选择基于复选框的状态。

<CheckBox Name="ShowFullNames_CheckBox" Content="Show Full Names" IsChecked="False"/>

我能够在后面的代码中将转换器连接到姓氏绑定,但是当我在绑定数据后尝试更改该转换器时出现错误(“绑定在使用后无法更改。”)。

我想也许我也可以将复选框 IsChecked 状态绑定到 ConverterParameter 或 Multibinding 的一个绑定,但无法让它工作。

<DataGridTextColumn MaxWidth="Infinity" MinWidth="150" Header="Last Name">
    <DataGridTextColumn.Binding>
        <MultiBinding Converter="myStringTruncator">
            <Binding Source="ShowFullNames_CheckBox" Path="IsChecked"/>
            <Binding Path="LastName"/>
        </MultiBinding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

在 myStringTruncator 的 Convert 方法中,第一个绑定只是用 DependencyProperty.UnsetValue 填充,而不是复选框的值。

可能有一种我没有看到的非常简单的方法来做到这一点。有什么想法吗?

【问题讨论】:

  • 从答案中可以看出,问题出在绑定上。为了更好地理解绑定在做什么,您可以在绑定上设置PresentationTraceSources.TraceLevel="High",它会向您显示一堆有用的信息(它可能会指出它没有找到名为@的Source 987654326@)。这是调试问题的好方法,尤其是对于继承的应用程序 ;-)

标签: c# wpf xaml binding converter


【解决方案1】:

您可以将转换器添加到 XAML 中的绑定。

<DataGridTextColumn Binding="{Binding Path=LastName, Converter={StaticResource YourConverter}"
                    MaxWidth="Infinity"
                    MinWidth="150"
                    Header="Last Name">

但是要绑定复选框的状态,您必须使用类似这样的东西(未经测试)

<DataGridTextColumn Header="Last Name">
  <DataGridTextColumn.Binding>
    <MultiBinding Converter="{StaticResource NameAndCheckBoxMultiValueConverter}">
      <Binding Path="LastName" />
      <Binding ElementName="myCheckBox" Path="IsChecked" />
    </MultiBinding>
  </DataGridTextColumn.Binding>
 </DataGridTextColumn>

还有转换器:

  using System;
    using System.Globalization;
    using System.Windows.Data;

    namespace TestWpf
    {
        public class NameAndCheckBoxMultiValueConverter: IMultiValueConverter
        {
            public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
            {
            var lastName = values[0] as String;
            if(lastName != null)
            {
                var isChecked = (bool)values[1];
                if (isChecked)
                {
                    return lastName.Substring(0,1);
                }
                return lastName;
            }
            return null;
            }

            public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }
    }

【讨论】:

  • 你在我编辑的时候回复了,但是一针见血。编辑后我需要的唯一更改是在 Multibinding Binding 上使用 ElementName 而不是 Source 到复选框。谢谢!
  • 也感谢您的详尽回复!这些细节确实有助于我更好地理解这一点。
  • 可以放在中。回答主题:Clone a Binding to assign a converter at runtime stackoverflow.com/a/14740448
  • 您需要在文件头中声明命名空间,例如:xmlns:testWpf="clr-namespace:TestWPF"。然后添加转换器:。这有帮助吗?
  • 我从未将转换器嵌套在另一个类中。刚刚发现,不可能:stackoverflow.com/a/4270348/3411327
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 2011-07-20
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多