Я создал пользовательский элемент управления, FontSelector, который объединяет ComboBox для выбора FontFamily и три параметра ToggleButtons для жирных, курсивных, подчеркнутых параметров. У меня возникла проблема с свойством SelectedItem ComboBox, затрагивающим все экземпляры этого элемента управления пользователя в том же окне. Например, изменение выбора ComboBox на одном, автоматически изменит другое. Для ясности. Я не хочу этого поведения. Я очень удивлен тем, что пользовательский контроль неявно влияет на другой элемент управления пользователя.Пользовательские элементы управления дочерними элементами Значение для нескольких экземпляров
XAML
<Grid x:Name="Grid" Background="White" DataContext="{Binding RelativeSource={RelativeSource AncestorType=local:FontSelector}}">
<ComboBox x:Name="comboBox" Width="135"
SelectedItem="{Binding Path=SelectedFontFamily}" Style="{StaticResource FontChooserComboBoxStyle}"
ItemsSource="{Binding Source={StaticResource SystemFontFamilies}}"/>
</Grid>
Код За
Среда CLR недвижимости, что SelectedItem в ComboBox является привязано. Код, показанный здесь, находится в коде управления пользователя позади файла, а не в ViewModel.
private FontFamily _SelectedFontFamily;
public FontFamily SelectedFontFamily
{
get
{
return _SelectedFontFamily;
}
set
{
if (_SelectedFontFamily != value)
{
_SelectedFontFamily = value;
// Modify External Dependency Property Value.
if (value != SelectedFont.FontFamily)
{
SelectedFont = new Typeface(value, GetStyle(), GetWeight(), FontStretches.Normal);
}
// Notify.
RaisePropertyChanged(nameof(SelectedFontFamily));
}
}
}
Зависимость от недвижимости, которая обновляет это значение, основанное на значении в ComboBox в SelectedItem собственности. Он эффективно упаковывает значение FontFamily в объект Typeface.
public Typeface SelectedFont
{
get { return (Typeface)GetValue(SelectedFontProperty); }
set { SetValue(SelectedFontProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedFont. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedFontProperty =
DependencyProperty.Register("SelectedFont", typeof(Typeface), typeof(FontSelector),
new FrameworkPropertyMetadata(new Typeface("Arial"), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(OnSelectedFontPropertyChanged)));
private static void OnSelectedFontPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var instance = d as FontSelector;
var newFont = e.NewValue as Typeface;
if (newFont != null)
{
instance.SelectedFontFamily = newFont.FontFamily;
}
}
EDIT
Я думаю, что я, возможно, понял, что происходит. Я могу воспроизвести его, привязав ItemsSource к следующему источнику просмотра коллекции.
<CollectionViewSource x:Key="SystemFontFamilies" Source="{Binding Source={x:Static Fonts.SystemFontFamilies}}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Source"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
Вы можете повторить поведение путем размещения 2 ComboBoxes и привязка их обоих к CollectionViewSource. Теперь они, казалось бы, неявно отслеживают друг друга SelectedItem. Даже без привязки данных за пределами ItemsSource. Казалось бы, CollectionViewSource каким-то образом играет роль в том, что такое SelectedItem.
Является ли свойство 'SelectedFontFamily' у вас ViewModel? Может быть, когда один UC обновит его, свойство обновит другие UC. –
Забыл упомянуть. Я не использую View Model для этого конкретного элемента управления. Источник привязки реализован в Code Behind File. Я решил не использовать виртуальную машину для этого, потому что, казалось, было много дополнительной работы, чтобы вернуть данные, сгенерированные VM, в свойство Dependency в фактическом коде управления пользователя. –
Я думаю, вопрос в том, что вы привязываете свойство SelectedFontFamily в окне. Потому что тогда изменение в одном элементе обновит форму модели формы, которая, в свою очередь, обновит другие элементы управления. – Geoffrey