2017-03-04 37 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