You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF自定义UserControl中自定义依赖参数无法正常生效问题

解决WPF自定义UserControl依赖属性不生效的问题

让我来帮你排查这个UCDataGrid控件的问题,我看了你的代码,发现几个关键错误导致ControlHeight和ControlWidth属性没起作用,下面一步步给你修正:

1. 绑定目标找错了!

你在DataGrid里写的RelativeSource={RelativeSource Self},是让DataGrid绑定自身的ControlWidth/ControlHeight属性,但这些属性是定义在父级UCDataGrid上的啊!得把绑定指向UCDataGrid才行:

修改XAML里的DataGrid绑定:

<DataGrid 
    Width="{Binding ControlWidth, RelativeSource={RelativeSource AncestorType={x:Type local:UCDataGrid}}}" 
    Height="{Binding ControlHeight, RelativeSource={RelativeSource AncestorType={x:Type local:UCDataGrid}}}"
    CellStyle="{StaticResource DataGridContentCellCentering}" 
    RowStyle="{StaticResource RowStyle}" 
    ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}" 
    Style="{StaticResource DataGridStyle}" 
    AlternatingRowBackground="White" 
    AlternationCount="2">
</DataGrid>

记得在XAML头部加上你的项目命名空间引用,比如xmlns:local="clr-namespace:你的项目命名空间",不然AncestorType找不到UCDataGrid类型。

2. 别画蛇添足:依赖属性不需要INotifyPropertyChanged

依赖属性本身已经自带属性变更通知机制了,你额外实现INotifyPropertyChanged不仅没用,还可能和依赖属性的通知逻辑冲突。而且你设置的DataContext = this;会导致外部使用UCDataGrid时,无法绑定到ViewModel的属性,这是UserControl开发的经典坑!

修正后台代码,删掉多余的接口实现:

public partial class UCDataGrid : UserControl
{
    public UCDataGrid()
    {
        InitializeComponent();
        // 删掉这行!DataContext = this;
    }

    // 用readonly修饰依赖属性字段,更符合WPF规范
    public static readonly DependencyProperty ControlHeightProperty = 
        DependencyProperty.Register(nameof(ControlHeight), typeof(int), typeof(UCDataGrid), new PropertyMetadata(0));

    public static readonly DependencyProperty ControlWidthProperty = 
        DependencyProperty.Register(nameof(ControlWidth), typeof(int), typeof(UCDataGrid), new PropertyMetadata(0));

    public int ControlHeight
    {
        get { return (int)GetValue(ControlHeightProperty); }
        set { SetValue(ControlHeightProperty, value); }
    }

    public int ControlWidth
    {
        get { return (int)GetValue(ControlWidthProperty); }
        set { SetValue(ControlWidthProperty, value); }
    }
}

3. 布局容器的限制要调整

你的外层Border和StackPanel都设了Height="auto",StackPanel会自动拉伸去适应内容,可能会覆盖你设置的ControlHeight值。如果希望ControlHeight完全生效,可以把Border的Height绑定到ControlHeight,然后让DataGrid占满剩余空间:

<Border Grid.Row="0" 
        Height="{Binding ControlHeight, RelativeSource={RelativeSource AncestorType={x:Type local:UCDataGrid}}}"
        x:Name="BorderEcs" Background="#9494a5" 
        BorderThickness="1,0,1,1" BorderBrush="#9494a5" 
        CornerRadius="10,10,0,0">
    <StackPanel>
        <Label x:Name="LblTitl" Content="" Margin="5,0,0,0" Foreground="#FFFFFF" FontFamily="Century Gothic" FontSize="13" />
        <DataGrid 
            Width="{Binding ControlWidth, RelativeSource={RelativeSource AncestorType={x:Type local:UCDataGrid}}}" 
            Height="*" <!-- 让DataGrid占满Border的剩余高度 -->
            CellStyle="{StaticResource DataGridContentCellCentering}" 
            RowStyle="{StaticResource RowStyle}" 
            ColumnHeaderStyle="{StaticResource ColumnHeaderStyle}" 
            Style="{StaticResource DataGridStyle}" 
            AlternatingRowBackground="White" 
            AlternationCount="2">
        </DataGrid>
    </StackPanel>
</Border>

最后验证使用

现在你再外部使用这个控件,设置的ControlWidth和ControlHeight就能正常生效了:

<us:UCDataGrid x:Name="d" ControlWidth="500" ControlHeight="300" />

内容的提问来源于stack exchange,提问作者hamza Benlaama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:04:54