и с новым годом.
Вот мой вопрос, выходит ли когда-либо привязка, созданная в стиле, из области видимости.
Позвольте мне объяснить, у меня есть текстовый блок с множественным связыванием значений двух элементов в списке «Имена», список строк в модели представления.
Я получаю доступ к этим элементам по индексу с помощью магической строки в xaml (yikes, я знаю, я не знаю, как поступить иначе, если я установил привязку к коллекции, событие itemChanged не вызывает привязку ...) .
Мне нужно получить изменения в значении, и я действительно не хочу создавать какие-либо средства доступа. Я хотел бы, чтобы все было обработано в представлении.
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text"
Value="" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsGroupedBy, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
Value="True">
<Setter Property="Text">
<Setter.Value>
<MultiBinding Converter="{StaticResource ConcatStringConvertor}"
UpdateSourceTrigger="PropertyChanged"
Mode="OneWay">
<Binding Path="Names[1]"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Window}"
UpdateSourceTrigger="PropertyChanged" />
<Binding Path="Names[2]"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Window}"
UpdateSourceTrigger="PropertyChanged" />
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsGroupedBy, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"
Value="False">
<Setter Property="Text" Value="0">
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
Я установил эту привязку в стиле с помощью источника данных на IsGroupedBy == true.
текст текстового поля устанавливается в 0, если «IsGroupedBy == false».
Это работает (когда useBinding имеет значение true, два моих значения объединены в текстовом блоке, в противном случае его значение равно «0».
Моя проблема возникает сейчас, когда я впервые устанавливаю для useBinding значение true, привязка создается. С этого момента, если я изменяю (обычно я очищаю его) мой список EVEN WITH IsGroupedBy TO FALSE, привязка оценивается;
Затем я получаю исключение аргумента для индекса вне диапазона. (который молчит и конечный пользователь никогда не узнает, но он не очень чистый и ориентированный на производительность ...)
System.Windows.Data Warning: 17 : Cannot get 'Item[]' value (type 'String') from 'Names' (type 'ObservableCollection`1'). BindingExpression:Path=Names[1]; DataItem='MainWindow' (Name=''); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException: ...
Я думал, что условное связывание решит эту проблему, но не ...
Я открыт для любых решений (особенно, если я могу найти способ удалить эти Имена [1] из привязок)
PS: простите за мой английский.
EDIT :
public ObservableCollection<string> Names { get; set; }
РЕДАКТИРОВАТЬ 2:
Я попробовал другой подход, я использую привязку приоритета, например так:
<TextBlock.Text>
<PriorityBinding>
<Binding Path="IsGroupedBy"
Converter="{StaticResource NotFalseToUnsetValueConverter}"
UpdateSourceTrigger="PropertyChanged"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Window}" />
<Binding Path="Names[1]"
UpdateSourceTrigger="PropertyChanged"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Window}" />
</PriorityBinding>
</TextBlock.Text>
public class NotFalseToUnsetValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var groupBy = value as bool?;
return (groupBy.Value == true)
? DependencyProperty.UnsetValue // evaluate next binding which is on array
: "dont bind array"; // stop at first binding and dont check array
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotImplementedException();
}
Но у меня возникла та же проблема, когда я впервые оцениваю привязку для Имен [1], она как-то регистрируется где-то.
И даже если я перестану привязываться ко второй привязке, любое опустошение в списке отправит ошибку:
System.Windows.Data Warning: 17 : Cannot get 'Item[]' value (type 'String') from 'Names' (type 'ObservableCollection`1'). BindingExpression:Path=Names[1]; DataItem='MainWindow' (Name=''); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') ArgumentOutOfRangeException:'System.ArgumentOutOfRangeException
РЕДАКТИРОВАТЬ 3:
Вот настоящая привязка:
<DataTemplate x:Key="customGroupValueTemplate">
<Grid Width="{Binding ElementName=uxGrid, Path=ActualWidth}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="60" />
</Grid.ColumnDefinitions>
<dxe:CheckEdit Grid.Column="0"
Initialized="cbGroupSummary_Initialized"
Checked="cbGroupSummary_Checked"
Unchecked="cbGroupSummary_Unchecked"
Content="{Binding Value}" />
<TextBlock Grid.Column="2"
Margin="10,0,0,0"
VerticalAlignment="Center"
Text="{Binding Path=(dxg:RowData.RowData).GroupSummaryData[0].Text, RelativeSource={RelativeSource TemplatedParent}}" />
<TextBlock Grid.Column="4"
Margin="10,0,0,0"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource GetPercentAsTextConv}"
UpdateSourceTrigger="PropertyChanged"
Mode="OneWay">
<Binding Path="(dxg:RowData.RowData).GroupSummaryData[1].Value"
RelativeSource="{RelativeSource Self}"
UpdateSourceTrigger="PropertyChanged" />
<Binding Path="(dxg:RowData.RowData).GroupSummaryData[2].Value"
RelativeSource="{RelativeSource Self}"
UpdateSourceTrigger="PropertyChanged" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<ProgressBar Grid.Column="5"
Width="100"
Height="10"
Margin="10 0 0 0"
HorizontalAlignment="Right"
VerticalAlignment="Center">
<ProgressBar.Value>
<MultiBinding Converter="{StaticResource GetPercentConv}"
UpdateSourceTrigger="PropertyChanged"
Mode="OneWay">
<Binding Path="(dxg:RowData.RowData).GroupSummaryData[1].Value"
RelativeSource="{RelativeSource TemplatedParent}"
UpdateSourceTrigger="PropertyChanged" />
<Binding Path="(dxg:RowData.RowData).GroupSummaryData[2].Value"
RelativeSource="{RelativeSource TemplatedParent}"
UpdateSourceTrigger="PropertyChanged" />
</MultiBinding>
</ProgressBar.Value>
</ProgressBar>
</Grid>
</DataTemplate>
Обратите внимание, что это шаблон.