아래 코드는 제가 수행하려고 시도하는 간단한 예제입니다. 내가 가진 모델의 데이터로 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을 반환합니다. –