Привязка пользовательского элемента управления не работает при изменении видимости родительского элемента управления
Всем привет.
У меня есть пользовательский элемент управления WPF, помещенный в сетку. Существует несколько стандартных элементов управления wpf, размещенных в одной сетке. Мой пользовательский элемент управления имеет свойство привязанной зависимости. Родительская сетка имеет datatrigger на видимости свойства и срабатывает, когда DataContext не равен null.
Использование моего пользовательского элемента управления:
<Grid Margin="5" DataContext="{Binding DetailedView}" > <Grid.Resources> <Style TargetType="{x:Type Grid}"> <Setter Property="Visibility" Value="Visible"/> <Style.Triggers> <DataTrigger Binding="{Binding}" Value="{x:Null}"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Style.Triggers> </Style> </Grid.Resources> <!- ... --> <!-- Grid layout --> <!-- ... --> <Grid Grid.Column="1" Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="320"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="32"/> <RowDefinition Height="32"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- My Custom control --> <controls:RatingControl x:Name="RcMangaRating" Grid.Column="1" Grid.Row="0" Value="{Binding Rating}" Size="24" Maximum="10" HorizontalAlignment="Right"/> <!-- Standard WPF control which have same binding as custom control --> <TextBlock Grid.Column="1" Grid.Row="1" FontSize="12" VerticalAlignment="Top" Text="{Binding Rating, StringFormat='{}Rating: {0:F2} from 10'}" Margin="0,5,5,0" HorizontalAlignment="Right"/> </Grid> </Grid>
Таким образом, когда видимость изменилась с свернутой на видимую, привязка для пользовательского элемента управления не работает, но для стандартного элемента управления привязка работает нормально. http://i.stack.imgur.com/bzZc7.png[^]
Но когда видимость сетки установлена на видимую и не меняется привязка для пользовательского элемента управления, он работает нормально. http://i.stack.imgur.com/ny5EH.png[^]
Область пользовательского стиля управления:
<Rectangle Grid.Row="0" Height="{TemplateBinding Width}" Width="{TemplateBinding Height}"> <Rectangle.Style> <Style> <Setter Property="Rectangle.OpacityMask"> <Setter.Value> <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> <GradientStop Color="Black" Offset="{Binding Value, RelativeSource={RelativeSource TemplatedParent}}"/> <GradientStop Color="Transparent" Offset="{Binding Value, RelativeSource={RelativeSource TemplatedParent}}"/> </LinearGradientBrush> </Setter.Value> </Setter> </Style> </Rectangle.Style> </Rectangle>
Что я уже пробовал:
Я удаляю триггер на свойстве видимости и все привязки работают нормально
<Grid Margin="5" DataContext="{Binding DetailedView}" > <!-- ... --> <!-- Grid layout --> <!-- ... --> <Grid Grid.Column="1" Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="320"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="32"/> <RowDefinition Height="32"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- My Custom control --> <controls:RatingControl x:Name="RcMangaRating" Grid.Column="1" Grid.Row="0" Value="{Binding Rating}" Size="24" Maximum="10" HorizontalAlignment="Right"/> <!-- Standard WPF control which have same binding as custom control --> <TextBlock Grid.Column="1" Grid.Row="1" FontSize="12" VerticalAlignment="Top" Text="{Binding Rating, StringFormat='{}Rating: {0:F2} from 10'}" Margin="0,5,5,0" HorizontalAlignment="Right"/> </Grid> </Grid>
У вас есть какие-нибудь идеи, в чем проблема?
--
Заранее благодарю вас.
Проблема решена
Решение:
Так, во-первых, существует проблема заключалась в объект onapplytemplate в моей власти. Я получаю TemplatePart в этом методе и инициализирую некоторые поля в элементе управления:
public override void OnApplyTemplate() { base.OnApplyTemplate(); _starItems = (ItemsControl)GetTemplateChild("PART_StarItems"); if (_starItems == null) return; var values = Enumerable.Range(0, (int)Maximum).Select(r => 0.0).ToList(); _starValues = new ObservableCollection<double>(values); }
Затем в обратном вызове OnChangeValue применяет _starValues к _starItems. Но в первый раз OnApplyTemplate после инициализации не вызывается (он вызывает после OnChangeValue и т. д.), а _starItems был равен null:
RatingControl control = d as RatingControl; if (control == null) return; if (control._starItems == null) return; // Here was problem /* Update values in _starValues */ _starItems.ItemsSource = _starValues;
Итак, я создал новые частные значения DependecyProperty (такие же, как _starValues) и привязал их к ItemsSource моего элемента управления, а также удалил TemplatePart и ненужные поля.
Исходный код[^]
Стиль шаблона управления[^]
Извините, проблема была не в контрольном шаблоне (как я изначально думал), а в моем коде есть реализация привязки для ItemsSource. По этой причине я изначально публикую только код XAML. Спасибо.
Спасибо моему руководителю за помощь и Совет