我在下面有一些代碼,這是我試圖做的一個簡單的例子。我正在使用轉換器嘗試使用我擁有的模型中的數據填充DataGrid。 DataGrid正在正確填充,但網格中的任何更改都不會被持久保存回對象。我已經將模式指定爲TwoWay。當我在轉換器ConvertBack方法上放置一個斷點時,它永遠不會被調用。WPF IValueConverter.ConvertBack不叫
我對WPF和MVVM相當陌生,所以我沒有看到我做錯了什麼。我不能改變模型,所以我想看看這個方法是否可行,除非有明確的方法。
XAML:
<Window x:Class="SampleBindingProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SampleBindingProblem"
Title="MainWindow" Height="400" Width="500">
<Window.Resources>
<ResourceDictionary>
<local:ScenarioDataTableConverter x:Key="ScenarioDataTableConverter" />
</ResourceDictionary>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Scenarios}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataGrid Margin="5" ItemsSource="{Binding Path=Options, Mode=TwoWay, Converter={StaticResource ScenarioDataTableConverter}}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
</Grid>
</Window>
App.xaml.cs:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace SampleBindingProblem
{
public class ColumnInfo
{
public static readonly String[] ColumnLabels = new String[] { "Variable1", "Variable2", "Variable3", "Variable4", "Variable5" };
}
public class ScenarioOption
{
public String Label { get; set; }
public String[] Variables { get; set; }
}
public class Scenario
{
public ScenarioOption[] Options { get; set; }
}
internal class ScenarioDataTableConverter : IValueConverter
{
public Object Convert (Object value, Type targetType, Object parameter, CultureInfo culture)
{
if (value == null)
return (null);
ScenarioOption[] options = (ScenarioOption[]) value;
DataTable table = new DataTable();
table.Columns.Add("Label", typeof(String));
for (Int32 c = 0; c < ColumnInfo.ColumnLabels.Length; ++c)
table.Columns.Add(ColumnInfo.ColumnLabels[c], typeof(String));
foreach (ScenarioOption option in options)
{
DataRow row = table.NewRow();
List<String> lst = new List<String>();
lst.Add(option.Label);
lst.AddRange(option.Variables);
row.ItemArray = lst.ToArray();
table.Rows.Add(row);
}
return (table.DefaultView);
}
public Object ConvertBack (Object value, Type targetType, Object parameter, CultureInfo culture)
{
return (null);
}
}
internal class ViewModel : INotifyPropertyChanged
{
public void RaisePropertyChanged (String property)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(property));
}
public event PropertyChangedEventHandler PropertyChanged = null;
public ObservableCollection<Scenario> Scenarios { get; set; }
public ViewModel()
{
Scenario s1 = new Scenario();
s1.Options = new ScenarioOption[] {
new ScenarioOption() { Label = "Opt1", Variables=new String[] { "1", "2", "3", "4", "5" } },
new ScenarioOption() { Label = "Opt2", Variables=new String[] { "2", "3", "4", "5", "6" } },
new ScenarioOption() { Label = "Opt3", Variables=new String[] { "3", "4", "5", "6", "7" } },
};
Scenario s2 = new Scenario();
s2.Options = new ScenarioOption[] {
new ScenarioOption() { Label = "Opt1", Variables=new String[] { "1", "2", "3", "4", "5" } },
new ScenarioOption() { Label = "Opt2", Variables=new String[] { "2", "3", "4", "5", "6" } },
new ScenarioOption() { Label = "Opt3", Variables=new String[] { "3", "4", "5", "6", "7" } },
};
this.Scenarios = new ObservableCollection<Scenario>();
this.Scenarios.Add(s1);
this.Scenarios.Add(s2);
}
}
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
private void Application_Startup (Object sender, StartupEventArgs e)
{
MainWindow window = new MainWindow();
window.DataContext = new ViewModel();
window.ShowDialog();
}
}
}
ConvertBack()方法當前返回null,因爲我尚未實現它,因爲它尚未被調用。 –