c# - 自定义控件,绑定(bind)到代码隐藏

标签 c# wpf

在我的自定义控件的代码后面绑定(bind)数据时遇到问题。显然,我必须使用 Generic.xaml 来设置控件的样式,并且我想绑定(bind)到控件 UserProfile.cs 中的数据。

这是背后的代码:

using System;
using System.Windows;
using System.Windows.Controls;

namespace Controls
{
    public class UserProfile : Control
    {
        static UserProfile()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(UserProfile), 
                new FrameworkPropertyMetadata(typeof(UserProfile)));
        }

        private Double _ProfilePhotoSize = 50;
        private Double ProfilePhotoSize
        {
            get { return _ProfilePhotoSize; }
            set
            {
                if (_ProfilePhotoSize != value)
                    _ProfilePhotoSize = value;
            }
        }
    }
}

这是带有绑定(bind)的 XAML,删除了最后一部分,因为不需要:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Controls">

    <Style TargetType="{x:Type local:NumericUpDown}">
        <Style.Resources>
            <SolidColorBrush x:Key="colour1" Color="#434953" />
            <SolidColorBrush x:Key="colour2" Color="#22252b" />
            <SolidColorBrush x:Key="colour3" Color="#606876" />
        </Style.Resources>

        <Setter Property="Width" Value="85" />
        <Setter Property="Margin" Value="5" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:NumericUpDown}">
                    <Border Focusable="{TemplateBinding Focusable}"
                            Width="{TemplateBinding Width}"
                            x:Name="Border">
                        <Grid Focusable="False">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"/>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="auto"/>
                            </Grid.ColumnDefinitions>

                            <Button x:Name="PART_DecreaseButton" 
                                    Grid.Column="0">
                                <Button.Content>
                                    <Path Data="M0,0 L1,0 0.5,1Z"
                                          Fill="White"
                                          Width="8"
                                          Height="6"
                                          Stretch="Fill"/>
                                </Button.Content>
                                <Button.Template>
                                    <ControlTemplate TargetType="Button">
                                        <Border Name="Border"
                                                Background="{DynamicResource colour1}" 
                                                Width="25" 
                                                Height="25"
                                                CornerRadius="5 0 0 5">
                                            <ContentPresenter />
                                        </Border>
                                        <ControlTemplate.Triggers>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter TargetName="Border" Property="Background" Value="{DynamicResource colour3}" />
                                            </Trigger>
                                        </ControlTemplate.Triggers>
                                    </ControlTemplate>
                                </Button.Template>
                            </Button>

                            <TextBox x:Name="PART_TextBox"
                                     Grid.Column="1"
                                     Foreground="White"
                                     Background="{DynamicResource colour2}"
                                     VerticalContentAlignment="Center"
                                     HorizontalContentAlignment="Center"
                                     HorizontalAlignment="Stretch" 
                                     BorderThickness="0"
                                     Focusable="False" Text="0" />

                            <Button x:Name="PART_IncreaseButton" 
                                    Grid.Column="2">
                                <Button.Content>
                                    <Path Data="M0,1 L1,1 0.5,0Z" 
                                          Width="8"
                                          Height="6"
                                          Fill="White" 
                                          Stretch="Fill" />
                                </Button.Content>
                                <Button.Template>
                                    <ControlTemplate TargetType="Button">
                                        <Border Name="Border" 
                                                Background="{DynamicResource colour1}" 
                                                Width="25" 
                                                Height="25"
                                                CornerRadius="0 5 5 0">
                                            <ContentPresenter />
                                        </Border>
                                        <ControlTemplate.Triggers>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter TargetName="Border" Property="Background" Value="{DynamicResource colour3}" />
                                            </Trigger>
                                        </ControlTemplate.Triggers>
                                    </ControlTemplate>
                                </Button.Template>
                            </Button>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="{x:Type local:UserProfile}">
        <Setter Property="DataContext" Value="{x:Type local:UserProfile}" />
        <Setter Property="Foreground" Value="White" />
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:UserProfile}">
                    <Grid x:Name="circleGrid" Width="{Binding Path=ProfilePhotoSize, RelativeSource={RelativeSource AncestorType={x:Type local:UserProfile}}}">
...

这是我遇到的绑定(bind)错误:

BindingExpression path error: 'ProfilePhotoSize' property not found on 'object' ''UserProfile' (Name='')'. BindingExpression:Path=ProfilePhotoSize; DataItem='UserProfile' (Name=''); target element is 'Grid' (Name='circleGrid'); target property is 'Width' (type 'Double')

编辑: 只是移动了一些代码,现在遇到了代码问题,我想根据用户制作控件的大小来调整边框大小,所以我创建了一个新的类和属性来获取 ProfilePhotoSize 然后将其除以一个数字。

代码隐藏

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace Controls
{
    public class UserProfile : Control
    {
        static UserProfile()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(UserProfile),
                new FrameworkPropertyMetadata(typeof(UserProfile)));
        }
    }
    public class UserProfileData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        private Double _ProfilePhotoSize = 50;
        public Double ProfilePhotoSize
        {
            get { return _ProfilePhotoSize; }
            set
            {
                if (_ProfilePhotoSize != value)
                    _ProfilePhotoSize = value;
                OnPropertyChanged("ProfilePhotoSize");
            }
        }
        private Double _ProfileBorderThickness = 3;
        public Double ProfileBorderThickness
        {
            get { return _ProfileBorderThickness; }
            set
            {
                double x = ProfilePhotoSize / 3;
                if (_ProfileBorderThickness != x)
                    _ProfileBorderThickness = x;
                OnPropertyChanged("ProfileBorderThickness");
            }
        }
    }
}

这是 XAML,绑定(bind)不再起作用:S

XAML

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Controls">

    <Style TargetType="{x:Type local:UserProfile}">
        <Setter Property="DataContext" Value="{x:Type local:UserProfile}" />
        <Setter Property="Foreground" Value="White" />
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:UserProfile}">
                    <Grid x:Name="circleGrid" Width="{Binding ProfilePhotoSize, RelativeSource={RelativeSource AncestorType={x:Type local:UserProfileData}}}">
                        <Grid.RowDefinitions>

最佳答案

将其更改为公共(public)属性。

    private Double _ProfilePhotoSize = 50;
    public Double ProfilePhotoSize
    {
        get { return _ProfilePhotoSize; }
        set
        {
            if (_ProfilePhotoSize != value)
                _ProfilePhotoSize = value;
        }
    }

关于c# - 自定义控件,绑定(bind)到代码隐藏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33817591/

相关文章:

wpf - 使用 MVVM 解决 Combobox 交互

wpf - 如何在 WPF ListView ( GridView ) 中创建组页脚

c# - 为什么适配器不工作?

C# 从 C++ DLL 捕获输出

c# - 如何使用 MVVM 折叠 Silverlight DataGrid 组?

c# - 按多个字符分割

c# - C++ DLL 在运行时抛出异常

C# - 在一个字符串中存储多个值

wpf - 是否有任何好的文档或网站显示 XAML GUI 的设计指南?

带数据库的 WPF MVVM 示例