Почему мой DependencyProperty в UserControl не установлен? - PullRequest
0 голосов
/ 25 апреля 2020

Я не могу правильно определить DependencyProperty в пользовательском UserControl.

Я связываю некоторые данные TB3270FontColor с собственным свойством, Foreground, и оно работает правильно.

Я пытаюсь привязать те же данные к пользовательскому свойству, CaretColor, но оно не работает, свойство, кажется, не установлено.

Вот мой код и значения свойств из Live Visual Tree

РЕДАКТИРОВАТЬ: На самом деле, как многие люди писали в комментариях, мой пользовательский DependencyProperty правильно определен и Binding работает правильно. Таким образом, проблема заключается в том, что Live Property Explorer в Visual Studio 2017 не отображает значение пользовательского свойства, если оно связано.

Я изменил свой код, чтобы показать его.

Вы можете попробовать отладить код с помощью VS и нажать «Показать свойства» на объекте «screenTB3270» в Live Visual Tree

MyUserControl.cs

namespace myPackageControls
{
    public partial class MyUserControl : UserControl
    {

        public MyUserControl()
        { InitializeComponent(); }

        public static readonly DependencyProperty CaretColorProperty =
        DependencyProperty.Register
        (
            "CaretColor",
            typeof(Color),
            typeof(MyUserControl),
            new FrameworkPropertyMetadata(Colors.Lime, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.Inherits)
        );

        public Color CaretColor
        {
            get { return (Color)GetValue(CaretColorProperty); }
            set { SetValue(CaretColorProperty, value); }
        }
    }
}

MyUserControl.xaml

<UserControl x:Class="myPackageControls.MyUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" d:DesignWidth="550" x:Name="tb3270" Height="Auto" Background="Black">
    <Grid Width="Auto" Height="Auto" HorizontalAlignment="Center">
        <Grid.RowDefinitions>
            <RowDefinition Height="20"/><RowDefinition Height="2*"/><RowDefinition Height="2*"/>
        </Grid.RowDefinitions>
        <TextBlock FontSize="14" Grid.Row="1" VerticalAlignment="Center" Height="50" TextWrapping="Wrap">
            <TextBlock.Foreground>
                <SolidColorBrush Color="{Binding ElementName=tb3270, Path=CaretColor}"/>
            </TextBlock.Foreground>
            The color <Run Text="{Binding ElementName=tb3270, Path=CaretColor}"></Run> is a Color Property, value NOT shown in Live Property Explorer
        </TextBlock>
        <TextBlock FontSize="14" Foreground="{Binding ElementName=tb3270, Path=Foreground}" Grid.Row="2" 
                   VerticalAlignment="Center" Height="50" TextWrapping="Wrap">
            The color <Run Text="{Binding ElementName=tb3270, Path=Foreground}"/> is bound to a Brush Property, value shown in Live Property Explorer
        </TextBlock>
    </Grid>
</UserControl>

MainWindow.xaml

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:myPackageControls="clr-namespace:myPackageControls"
    xmlns:local="clr-namespace:myPackage"
    x:Class="myPackage.MainWindow"
    mc:Ignorable="d"
    x:Name="mainWindow" ResizeMode="CanResize" Width="500" Height="230">
    <Window.Resources>
        <local:ColorToBrushConverter x:Key="colorToBrushConverter"/>
    </Window.Resources>
    <Grid>
        <myPackageControls:MyUserControl x:Name="screenTB3270" Width="Auto" Height="Auto" VerticalAlignment="Top"
                               Foreground = "{Binding TB3270FontColor, 
                                   Converter={StaticResource colorToBrushConverter}, Mode=OneWay}"
                               CaretColor = "{Binding TB3270FontColor, Mode=OneWay}">
        </myPackageControls:MyUserControl>
        <Button x:Name="button" Content="Change color" HorizontalAlignment="Center" Margin="0,0,0,20" 
            VerticalAlignment="Bottom" Width="100" Height="30" Click="Button_Click"/>
    </Grid>
</Window>

MainWindow.xaml.cs

namespace myPackage
{    
    public partial class MainWindow : Window
    {
        Color[] colori = { Colors.Red, Colors.Blue, Colors.Yellow, Colors.Violet, Colors.Orange, Colors.Lime};
        int i = 0;
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new SettingsViewModel();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ((SettingsViewModel)this.DataContext).TB3270FontColor = colori[i++%colori.Length];
        }
    }

    [ValueConversion(typeof(Color?), typeof(Brush))]
    public class ColorToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(Brush))
                throw new InvalidOperationException("The target must be a Color");
            SolidColorBrush brush = new SolidColorBrush((Color)value);
            return brush;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (value is SolidColorBrush colorBrush)
            {
                return colorBrush.Color;
            }
            else return Colors.Lime;
        }
    }
}

SettingsViewModel.cs

public class SettingsViewModel : NotifyChangeClass
{
    private Color _fontColor = Colors.Lime;

    public Color TB3270FontColor
    {
        get { return _fontColor; }
        set
        {
            _fontColor = value;
            NotifyPropertyChanged("TB3270FontColor");
        }
    }
}

public class NotifyChangeClass : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Свойства экземпляра MyUserControl, с которого запускается программа: (Живое визуальное дерево VS2017, Показать свойства на "screenTB3270")

Properties of the istance of MyUserControl Заранее спасибо!

...