ObservableCollection 두 개가있는 클래스가 있습니다. 여기서 TimeValue는 (INotifyPropertyChanged를 통해) 변경 알림이있는 사용자 지정 DateTime/Value 쌍인 TimeValue>입니다. 나는이 표적과 실제를 부른다.WPF DataGrid - MultiBinding이있는 TimeSeries 결합, 변경 알림을 잃습니다. 왜?
차트에 이들을 바인딩하면 모든 것이 완벽하게 작동하고 두 개의 LineSeries를 얻게됩니다. DataGrid에 바인딩 할 때 "Date"열과 "Value"열이 함께 있으면 완벽하게 다시 작동합니다. 나는 심지어 내가 필요로하는 TwoWay 바인딩을 얻는다.
그러나 "대상"과 "실제"에 대해 각각 "날짜"열과 열을 가진 DataGrid가 있어야합니다. 문제는 범위의 모든 날짜를 나열해야하지만 일부 날짜는 대상, 실제 또는 둘 다에서 해당 값을 갖지 않을 수 있다는 것입니다.
그래서 Target과 Actuals를 입력으로 사용하고 원본 중 하나에 값이없는 경우 null 값이 결합 된 TimeSeriesC를 출력하는 MultiBinding을 수행하기로 결정했습니다.
작동하지만 기본 데이터의 변경에 응답하지 않습니다.
이 (한 ObservableCollection에 바인딩) 잘 작동이 작동,하지만 처음으로 초기화 할 때
<ctrls:DataGrid Grid.Row="1" Height="400" AutoGenerateColumns="False" CanUserDeleteRows="False" SelectionUnit="Cell">
<ctrls:DataGrid.ItemsSource>
<Binding Path="Targets"/>
<!--<MultiBinding Converter="{StaticResource TargetActualListConverter}">
<Binding Path="Targets"/>
<Binding Path="Actuals"/>
</MultiBinding>-->
</ctrls:DataGrid.ItemsSource>
<ctrls:DataGrid.Columns>
<ctrls:DataGridTextColumn Header="Date" Binding="{Binding Date,StringFormat={}{0:ddd, MMM d}}"/>
<ctrls:DataGridTextColumn Header="Target" Binding="{Binding Value}"/>
<!--<ctrls:DataGridTextColumn Header="Target" Binding="{Binding Value[0]}"/>
<ctrls:DataGridTextColumn Header="Actual" Binding="{Binding Value[1]}"/>-->
</ctrls:DataGrid.Columns>
. 응답이 변경되지-통지합니다 : 그것은 값을 표시하기 때문에 내가 너무 멀리 떨어져있을 수 없습니다
class TargetActualListConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
TimeSeries<double> Targets = values[0] as TimeSeries<double>;
TimeSeries<double> Actuals = values[1] as TimeSeries<double>;
DateTime[] range = TimeSeries<double>.GetDateRange(Targets, Actuals);//Get min and max Dates
int count = (range[1] - range[0]).Days;//total number of days
DateTime currDate = new DateTime();
TimeSeries<double?[]> combined = new TimeSeries<double?[]>();
for (int i = 0; i < count; i++)
{
currDate = range[0].AddDays(i);
double?[] vals = { Targets.Dates.Contains(currDate) ? (double?)Targets.GetValueByDate(currDate) : null, Actuals.Dates.Contains(currDate) ? (double?)Actuals.GetValueByDate(currDate) : null };
combined.Add(new TimeValue<double?[]>(currDate, vals));
}
return combined;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
TimeSeries<double?[]> combined = value as TimeSeries<double?[]>;
TimeSeries<double> Targets = new TimeSeries<double>();
TimeSeries<double> Actuals = new TimeSeries<double>();
foreach (TimeValue<double?[]> tv in combined)
{
if(tv.Value[0]!=null)
Targets.Add(new TimeValue<double>(tv.Date,(double)tv.Value[0]));
if (tv.Value[1] != null)
Actuals.Add(new TimeValue<double>(tv.Date, (double)tv.Value[1]));
}
TimeSeries<double>[] result = { Targets, Actuals };
return result;
}
}
: 여기
그리고
<ctrls:DataGrid Grid.Row="1" Height="400" AutoGenerateColumns="False" CanUserDeleteRows="False" SelectionUnit="Cell">
<ctrls:DataGrid.ItemsSource>
<!--<Binding Path="Targets"/>-->
<MultiBinding Converter="{StaticResource TargetActualListConverter}">
<Binding Path="Targets"/>
<Binding Path="Actuals"/>
</MultiBinding>
</ctrls:DataGrid.ItemsSource>
<ctrls:DataGrid.Columns>
<ctrls:DataGridTextColumn Header="Date" Binding="{Binding Date,StringFormat={}{0:ddd, MMM d}}"/>
<!--<ctrls:DataGridTextColumn Header="Target" Binding="{Binding Value}"/>-->
<ctrls:DataGridTextColumn Header="Target" Binding="{Binding Value[0]}"/>
<ctrls:DataGridTextColumn Header="Actual" Binding="{Binding Value[1]}"/>
</ctrls:DataGrid.Columns>
내 IMultiValueConverter입니다.
내가 뭘 잘못하고 있니? 또는이 작업을 수행하는 더 쉬운 방법이 있습니까?
감사합니다.
감사 rmoore. 불행히도, 내가 가진 설정은 심지어 CollectionChanged 이벤트에 응답하지 않습니다. 나는 W/CompositeCollections를 시도했지만, 표시하고자하는 컬렉션이 두 개의 입력과 같은 크기가 아니기 때문에 어떻게 작동하는지 알 수 없다. 이상하게도 Convert 메서드는 초기 화면에서 한 번만 (값 당) 호출되며 다시는 호출되지 않습니다. – AdrianoFerrari
그런 경우, 더 이상 알지 못하면서 이것을 해결하는 가장 쉬운 방법은 대상 및/또는 실제를 병합 할 수있는 일종의 래퍼 클래스를 만드는 것입니다. 그런 다음 이러한 래퍼에 대해 ObservableCollection을 하나만 만들면 훨씬 쉽게 바인딩 할 수 있습니다. – rmoore
그런 식으로해야 할 것 같네요. 내가 의도 한 방식대로 처리하면 여기에 다시 게시 할 것이므로보다 직관적 일 것입니다. 감사합니다. rmoore. 이 점을 대답으로 표시하지 않고 점수를 부여 할 여지가 있습니까? – AdrianoFerrari