2017-03-04 40 views
0

我正在尝试使用MultiBinding来更新DataGridTextColumn。MultiBinding无法在DataGridTextColumn中工作

<Window x:Class="WPFBench.MultiBindingProblem" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:WPFBench" 
    mc:Ignorable="d" 
    Title="MultiBindingProblem" Height="300" Width="300"> 
<Window.Resources> 
    <local:MultiValueConverter x:Key="MultiValueConverter"/> 
</Window.Resources> 
<Grid> 
    <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" 
        ItemsSource="{Binding TableA}" ColumnWidth="100*"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="Value" Binding="{Binding Value}"/> 
      <DataGridTextColumn Header="MultiValue"> 
       <DataGridTextColumn.Binding> 
        <MultiBinding Converter="{StaticResource MultiValueConverter}"> 
         <Binding Path="Value"/> 
         <Binding Path="Value"/> 
        </MultiBinding> 
       </DataGridTextColumn.Binding> 
      </DataGridTextColumn> 
     </DataGrid.Columns> 
    </DataGrid> 

</Grid> 

这里是转换器...

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Data; 

namespace WPFBench 
{ 
    public class MultiValueConverter : IMultiValueConverter 
    { 
     public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
     { 
      return values[0]; 
     } 

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

后面的代码...

using System; 
using System.Collections.Generic; 
using System.Data; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Shapes; 

namespace WPFBench 
{ 
/// <summary> 
/// Interaction logic for MultiBindingProblem.xaml 
/// </summary> 
public partial class MultiBindingProblem : Window 
{ 
    DataTable _tableA = new DataTable(); 
    public MultiBindingProblem() 
    { 
     InitializeComponent(); 
     _tableA.Columns.Add(new DataColumn("Value", typeof(double))); 
     _tableA.Rows.Add(0.0); 
     _tableA.Rows.Add(1.0); 
     _tableA.Rows.Add(2.0); 
     _tableA.Rows.Add(3.0); 
     _tableA.Rows.Add(4.0); 
     DataContext = this; 
    } 
    public DataTable TableA 
    { 
     get { return _tableA; } 
    } 
} 
} 

单绑定列被更新。多值转换器被调用。多值列保持空白。我究竟做错了什么?

+0

你是否约束所有相同的事情? – Noctis

回答

0

假设你Value是值类型像一个int,而不是一个string,这个问题是因为没有从对象到字符串的隐式转换。

尝试从Convert方法返回

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
{ 
    return String.Format("{0}", values[0]); // don't return an object values[0]; 
} 

还放置一个断点,并检查values是否按预期正确填充。

简单的演示,以证明这是正确答案。

使用简单,粗糙的视图模型

public class DemoRoughTable 
{ 
    public int Value { get; set; } // Notice that it's not a string 
} 
public class DemoRoughViewModel 
{ 
    public List<DemoRoughTable> TableA { get; set; } = new List<DemoRoughTable>() 
    { 
     new DemoRoughTable() { Value = 1 }, new DemoRoughTable() { Value = 2 } 
    }; 
} 

从主窗口

private void button_Click(object sender, RoutedEventArgs e) 
{ 
    MultiBindingProblem probl = new MultiBindingProblem(); 
    probl.DataContext = new DemoRoughViewModel(); 
    probl.Show(); 
} 

的按钮,启动你的问题窗口HTH

+0

如果您有任何疑问,请在此处注明并让我知道。 – 2017-03-04 09:40:44

+0

的确,我增加了值[0] .ToString(),并且所有东西都开始工作。值数组包含双打。单个绑定显然具有向字符串的隐式转换,但不是多重绑定。这似乎是错误的。 – AQuirky

+0

我理解你的比较和你的意思,但我会以这种方式回复:区别不在于单一和多重绑定,而是在使用转换器或不使用转换器之间:它是将转换引入'object',而不是绑定类型。 – 2017-03-04 21:05:08

0

我是什么做错了?

一个DataGridTextColumnBinding属性应该被设置为BindingBase对象,而不是到数据绑定

如果要显示由转换器返回的值列,你应该使用DataGridTemplateColumn

<DataGridTemplateColumn Header="MultiValue"> 
    <DataGridTemplateColumn.CellTemplate> 
     <DataTemplate> 
      <TextBlock> 
       <TextBlock.Text> 
        <MultiBinding Converter="{StaticResource MultiValueConverter}"> 
         <Binding Path="Value"/> 
         <Binding Path="Value"/> 
        </MultiBinding> 
       </TextBlock.Text> 
      </TextBlock> 
     </DataTemplate> 
    </DataGridTemplateColumn.CellTemplate> 
</DataGridTemplateColumn> 

还要确保你从转换器返回一个字符串:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
{ 
    return values[0].ToString(); 
} 
1

只要您将values[0]转换为方法IMultiValueConverter中的string表示形式(正如其他解答所解释的那样),您的示例应该可以正常工作。但是,这里的示例有点奇怪,因为不需要MultiBinding。 (我知道你知道他们,因为第一列显示了一个更合适的方法)。

无论如何,我认为你需要一个DataGridTextColumnBinding财产MultiBinding,当你想设置的Binding动态。在这种情况下,您应该发送DataContext和路径字符串,并在IMultiValueConverter中检索其值。有an example here,类似于这种情况,其中Binding根据DataGridTextColumn的标题中的值而更改。

希望它有帮助。

+0

当然这个例子很奇怪......我从实际的代码中大大地简化了它,所以我可以在这里正确地提出这个问题。 我想要做的多绑定是将两列合并为一个以节省空间。一列是双列,一列是字符串。 – AQuirky