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

