WPF - 如何绑定到 UserControl 中的 UserControl 属性 以便子更新父?
WPF - How to bind to a UserControl property within a UserControl so that the child updates the parent?
我正在尝试使用我的自定义滑块控件 LabelSlider 创建一个基本的颜色更改 UserControl。我可以通过代码设置颜色,但是如果我移动滑块或在文本框中输入文本,它不会更新颜色。
LabelSlider XAML:
<Slider x:Name="ucSlider" x:FieldModifier="private" Margin="{Binding SliderSpacing, FallbackValue=5, Converter={StaticResource DoubleToMargin}}" VerticalAlignment="Center" Grid.Column="1" Width="{Binding SliderWidth}" MaxWidth="{Binding SliderWidth}" FontFamily="Segoe UI" Value="{Binding Value, Mode=TwoWay}" SmallChange="1" Maximum="255"/>
<TextBox x:Name="ucTextBox" x:FieldModifier="private" Text="{Binding Value, TargetNullValue=0, Mode=TwoWay}" Margin="{Binding TextBoxSpacing, FallbackValue=5, Converter={StaticResource DoubleToMargin}}" Grid.Column="2" PreviewKeyDown="LabelSlider_PreviewKeyDown" PreviewTextInput="LabelSlider_PreviewTextInput" MaxLength="3" Width="30" MaxWidth="30" FontFamily="Segoe UI" TextChanged="LabelSlider_TextChanged"/>
LabelSlider 代码隐藏:
public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register
(
"Value",
typeof(int),
typeof(LabelSlider),
new PropertyMetadata(null)
);
颜色选择XAML:
<UserControl x:Class="Homuli.UserControls.ColourSelection"
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"
xmlns:local="clr-namespace:Homuli.UserControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" x:Name="colourSelection">
<StackPanel Margin="5,0,0,0" DataContext="{Binding ElementName=colourSelection}">
<local:LabelSlider Label="R" SliderSpacing="6" SliderWidth="100" Value="{Binding R, FallbackValue=255, TargetNullValue=0}" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,-4"/>
<local:LabelSlider Label="G" SliderSpacing="5" SliderWidth="100" Value="{Binding G, FallbackValue=0, TargetNullValue=0}" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,-4"/>
<local:LabelSlider Label="B" SliderSpacing="6" SliderWidth="100" Value="{Binding B, FallbackValue=0, TargetNullValue=0}" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,-4"/>
<StackPanel Orientation="Horizontal">
<local:LabelTextBox Label="Hex" Spacing="15" TextBoxWidth="50" Text="{Binding Hex}" MaxLength="6" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Rectangle Fill="{Binding Colour}" Height="26" Width="26" Margin="26,0,0,0" Stroke="Black" />
</StackPanel>
</StackPanel>
后面的 ColourSelection 代码:
public partial class ColourSelection : UserControl
{
public ColourSelection()
{
InitializeComponent();
}
public SolidColorBrush Colour
{
get { return (SolidColorBrush)GetValue(ColourProperty); }
set { SetValue(ColourProperty, value); }
}
public static readonly DependencyProperty ColourProperty = DependencyProperty.Register
(
"Colour",
typeof(SolidColorBrush),
typeof(ColourSelection),
new PropertyMetadata(null)
);
public int R
{
get { return (int)GetValue(RProperty); }
set
{
if (value <= 255 && value >= 0)
{
SetValue(RProperty, value);
UpdateColour();
}
}
}
public static readonly DependencyProperty RProperty = DependencyProperty.Register
(
"R",
typeof(int),
typeof(ColourSelection),
new PropertyMetadata()
);
public int G
{
get { return (int)GetValue(GProperty); }
set
{
if (value <= 255 && value >= 0)
{
SetValue(GProperty, value);
UpdateColour();
}
}
}
public static readonly DependencyProperty GProperty = DependencyProperty.Register
(
"G",
typeof(int),
typeof(ColourSelection),
new PropertyMetadata(null)
);
public int B
{
get { return (int)GetValue(BProperty); }
set
{
if (value <= 255 && value >= 0)
{
SetValue(BProperty, value);
UpdateColour();
}
}
}
public static readonly DependencyProperty BProperty = DependencyProperty.Register
(
"B",
typeof(int),
typeof(ColourSelection),
new PropertyMetadata(null)
);
void UpdateColour()
{
Colour = new SolidColorBrush(Color.FromRgb((byte)R, (byte)G, (byte)B));
}
}
任何帮助将不胜感激。
当 DP 发生变化时,它通过静态对象发生 BProperty
。 setter
中的代码
if (value <= 255 && value >= 0)
{
SetValue(RProperty, value);
UpdateColour();
}
没有执行。
您需要添加 属性 更改回调(对于 R
、G
、B
属性):
public int B
{
get { return (int)GetValue(BProperty); }
set { SetValue(BProperty, value); }
}
public static readonly DependencyProperty BProperty = DependencyProperty.Register
(
"B",
typeof(int),
typeof(ColourSelection),
new PropertyMetadata(0, PropertyChangedCallback)
);
private static void PropertyChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if ((int) e.NewValue <= 255 && (int) e.NewValue >= 0)
((ColourSelection) obj).UpdateColour();
}
我也不建议像这样替换 userControl 中的 dataContext DataContext="{Binding ElementName=colourSelection}"
。而是在绑定中使用 ElementName
:
<local:LabelSlider Label="R" SliderSpacing="6" SliderWidth="100"
Value="{Binding R, ElementName=colourSelection, FallbackValue=255, TargetNullValue=0}"
我正在尝试使用我的自定义滑块控件 LabelSlider 创建一个基本的颜色更改 UserControl。我可以通过代码设置颜色,但是如果我移动滑块或在文本框中输入文本,它不会更新颜色。
LabelSlider XAML:
<Slider x:Name="ucSlider" x:FieldModifier="private" Margin="{Binding SliderSpacing, FallbackValue=5, Converter={StaticResource DoubleToMargin}}" VerticalAlignment="Center" Grid.Column="1" Width="{Binding SliderWidth}" MaxWidth="{Binding SliderWidth}" FontFamily="Segoe UI" Value="{Binding Value, Mode=TwoWay}" SmallChange="1" Maximum="255"/>
<TextBox x:Name="ucTextBox" x:FieldModifier="private" Text="{Binding Value, TargetNullValue=0, Mode=TwoWay}" Margin="{Binding TextBoxSpacing, FallbackValue=5, Converter={StaticResource DoubleToMargin}}" Grid.Column="2" PreviewKeyDown="LabelSlider_PreviewKeyDown" PreviewTextInput="LabelSlider_PreviewTextInput" MaxLength="3" Width="30" MaxWidth="30" FontFamily="Segoe UI" TextChanged="LabelSlider_TextChanged"/>
LabelSlider 代码隐藏:
public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register
(
"Value",
typeof(int),
typeof(LabelSlider),
new PropertyMetadata(null)
);
颜色选择XAML:
<UserControl x:Class="Homuli.UserControls.ColourSelection"
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"
xmlns:local="clr-namespace:Homuli.UserControls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" x:Name="colourSelection">
<StackPanel Margin="5,0,0,0" DataContext="{Binding ElementName=colourSelection}">
<local:LabelSlider Label="R" SliderSpacing="6" SliderWidth="100" Value="{Binding R, FallbackValue=255, TargetNullValue=0}" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,-4"/>
<local:LabelSlider Label="G" SliderSpacing="5" SliderWidth="100" Value="{Binding G, FallbackValue=0, TargetNullValue=0}" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,-4"/>
<local:LabelSlider Label="B" SliderSpacing="6" SliderWidth="100" Value="{Binding B, FallbackValue=0, TargetNullValue=0}" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,-4"/>
<StackPanel Orientation="Horizontal">
<local:LabelTextBox Label="Hex" Spacing="15" TextBoxWidth="50" Text="{Binding Hex}" MaxLength="6" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Rectangle Fill="{Binding Colour}" Height="26" Width="26" Margin="26,0,0,0" Stroke="Black" />
</StackPanel>
</StackPanel>
后面的 ColourSelection 代码:
public partial class ColourSelection : UserControl
{
public ColourSelection()
{
InitializeComponent();
}
public SolidColorBrush Colour
{
get { return (SolidColorBrush)GetValue(ColourProperty); }
set { SetValue(ColourProperty, value); }
}
public static readonly DependencyProperty ColourProperty = DependencyProperty.Register
(
"Colour",
typeof(SolidColorBrush),
typeof(ColourSelection),
new PropertyMetadata(null)
);
public int R
{
get { return (int)GetValue(RProperty); }
set
{
if (value <= 255 && value >= 0)
{
SetValue(RProperty, value);
UpdateColour();
}
}
}
public static readonly DependencyProperty RProperty = DependencyProperty.Register
(
"R",
typeof(int),
typeof(ColourSelection),
new PropertyMetadata()
);
public int G
{
get { return (int)GetValue(GProperty); }
set
{
if (value <= 255 && value >= 0)
{
SetValue(GProperty, value);
UpdateColour();
}
}
}
public static readonly DependencyProperty GProperty = DependencyProperty.Register
(
"G",
typeof(int),
typeof(ColourSelection),
new PropertyMetadata(null)
);
public int B
{
get { return (int)GetValue(BProperty); }
set
{
if (value <= 255 && value >= 0)
{
SetValue(BProperty, value);
UpdateColour();
}
}
}
public static readonly DependencyProperty BProperty = DependencyProperty.Register
(
"B",
typeof(int),
typeof(ColourSelection),
new PropertyMetadata(null)
);
void UpdateColour()
{
Colour = new SolidColorBrush(Color.FromRgb((byte)R, (byte)G, (byte)B));
}
}
任何帮助将不胜感激。
当 DP 发生变化时,它通过静态对象发生 BProperty
。 setter
if (value <= 255 && value >= 0)
{
SetValue(RProperty, value);
UpdateColour();
}
没有执行。
您需要添加 属性 更改回调(对于 R
、G
、B
属性):
public int B
{
get { return (int)GetValue(BProperty); }
set { SetValue(BProperty, value); }
}
public static readonly DependencyProperty BProperty = DependencyProperty.Register
(
"B",
typeof(int),
typeof(ColourSelection),
new PropertyMetadata(0, PropertyChangedCallback)
);
private static void PropertyChangedCallback(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
if ((int) e.NewValue <= 255 && (int) e.NewValue >= 0)
((ColourSelection) obj).UpdateColour();
}
我也不建议像这样替换 userControl 中的 dataContext DataContext="{Binding ElementName=colourSelection}"
。而是在绑定中使用 ElementName
:
<local:LabelSlider Label="R" SliderSpacing="6" SliderWidth="100"
Value="{Binding R, ElementName=colourSelection, FallbackValue=255, TargetNullValue=0}"