Wpf 具有多个文本框的UserControl';将其聚合为从属财产

Wpf 具有多个文本框的UserControl';将其聚合为从属财产,wpf,user-controls,binding,ip-address,dependency-properties,Wpf,User Controls,Binding,Ip Address,Dependency Properties,我试图构建一个用户控件,它本质上是一个IPv4地址“文本框” 在UserControl中有4个文本框,每个文本框之间有一个包含单个“.”的文本块: <Grid Grid.IsSharedSizeScope="True"> <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="GroupA" /> <ColumnDefinition Width="*"

我试图构建一个用户控件,它本质上是一个IPv4地址“文本框”

在UserControl中有4个文本框,每个文本框之间有一个包含单个“.”的文本块:

<Grid Grid.IsSharedSizeScope="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition SharedSizeGroup="GroupA" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition SharedSizeGroup="GroupA" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition SharedSizeGroup="GroupA" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition SharedSizeGroup="GroupA" />
    </Grid.ColumnDefinitions>
    <TextBox Grid.Column="0" TabIndex="0" x:Name="TextOctet1" />
    <TextBlock Grid.Column="1" Text="." />
    <TextBox Grid.Column="2" TabIndex="1" x:Name="TextOctet2" />
    <TextBlock Grid.Column="3" Text="." />
    <TextBox Grid.Column="4" TabIndex="2" x:Name="TextOctet3" />
    <TextBlock Grid.Column="5" Text="." />
    <TextBox Grid.Column="6" TabIndex="3" x:Name="TextOctet4" />
</Grid>
但我相信这与我想要的正好相反。多值转换器将多个业务逻辑属性合并为单个属性,以便文本框绑定

相反,我希望绑定单个业务逻辑属性(一个表示IPv4地址的字符串),并让每个八位字节显示在自己的文本框中。然后,如果任何八位字节文本框发生更改,IPAddress dependency属性将更新


这可能吗?我是否以正确的方式思考这个问题?

有很多方法可以做到这一点。只需为八位字节创建私有属性并将文本框绑定到这些属性,例如:

<TextBox Text={Binding RelativeSource={AncestorType UserControl}, Path=Octet1}, Mode=TwoWay"/>
编辑:

双向绑定有点棘手,因为您需要更改通知才能更新UI。我处理这个问题的方法可能是创建一个视图模型类,该类具有八位字节和IP地址属性,并实现
INotifyPropertyChanged
,然后在UserControl的构造函数中创建它的实例,并将所有UI控件绑定到属性。这样,当视图模型上的
IPAddress
被设置时,setter可以解析值,更新八位组属性,它们将引发
PropertyChanged
并更新UI

然后在
UserControl
中,我将处理视图模型上的
PropertyChanged
,并在视图模型上的
IPAddress
属性更改时,在控件上设置
IPAddress
依赖属性。(这并不像听起来那么奇怪。)

您还需要编写一个函数,将视图模型的
IPAddress
属性设置为
IPAddress
依赖项属性的值,并在 注册DP


因此,事件链将是:设置控件上的
IPAddress
属性->DP回调设置视图模型上的
IPAddress
属性->设置器解析八位字节并设置
Octet
属性->属性提升
PropertyChanged
->绑定将更改的值推出到
UserControl
中的UI控件。另一方面,它是:用户在视图模型->用户控件句柄
PropertyChanged
上输入一个八位字节->八位字节设置器设置
IPAddress
,并设置
IPAddress
依赖属性。

有很多方法可以做到这一点。只需为八位字节创建私有属性并将文本框绑定到这些属性,例如:

<TextBox Text={Binding RelativeSource={AncestorType UserControl}, Path=Octet1}, Mode=TwoWay"/>
编辑:

双向绑定有点棘手,因为您需要更改通知才能更新UI。我处理这个问题的方法可能是创建一个视图模型类,该类具有八位字节和IP地址属性,并实现
INotifyPropertyChanged
,然后在UserControl的构造函数中创建它的实例,并将所有UI控件绑定到属性。这样,当视图模型上的
IPAddress
被设置时,setter可以解析值,更新八位组属性,它们将引发
PropertyChanged
并更新UI

然后在
UserControl
中,我将处理视图模型上的
PropertyChanged
,并在视图模型上的
IPAddress
属性更改时,在控件上设置
IPAddress
依赖属性。(这并不像听起来那么奇怪。)

您还需要编写一个函数,将视图模型的
IPAddress
属性设置为
IPAddress
依赖项属性的值,并在 注册DP


因此,事件链将是:设置控件上的
IPAddress
属性->DP回调设置视图模型上的
IPAddress
属性->设置器解析八位字节并设置
Octet
属性->属性提升
PropertyChanged
->绑定将更改的值推出到
UserControl
中的UI控件。另一方面,它是:用户在视图模型->用户控件句柄
PropertyChanged
上输入一个八位字节->八位字节setter设置
IPAddress
,并设置
IPAddress
依赖属性。

因此,如果我将UserControl的IPAddress依赖属性绑定到一些格式正确的字符串,八位字节是如何更新的?(双向绑定):那么我认为您需要实现一个视图模型。看我的编辑哈。。。所以我第一次尝试了所有这些东西。。。这根本不起作用。后来我发现,当我绑定到与默认数据值相同的数据时,dp中有默认数据导致它显示为空:public static readonly dependencProperty IPAddressProperty=dependencProperty.Register(“IPAddress”)、typeof(string)、typeof(IPBox)、new UIPropertyMetadata(“0.0.0”,新属性更改回调(IPAddressChanged));。当我删除“0.0.0.0”后,一切都开始工作了。谢谢你花时间看这个并帮助我!因此,如果我将UserControl的IPAddress依赖属性绑定到某个格式正确的字符串,如何更新八位字节?(双向绑定):那么我认为您需要实现一个视图模型。看我的编辑哈。。。所以我第一次尝试了所有这些东西。。。这根本不起作用。后来我发现,当我绑定到与默认数据值相同的数据时,dp中有默认数据导致它显示为空:public static readonly dependencProperty ipaddress property=dependencProperty.Register(“IPA”)
<TextBox Text={Binding RelativeSource={AncestorType UserControl}, Path=Octet1}, Mode=TwoWay"/>
private int _Octet1;
private int Octet1
{
   get { return _Octet1; }
   set
   {
     _Octet1 = value;
     UpdateIPAddress();
   }
}

private void UpdateIPAddress()
{
   IPAddress = string.Format("{0}.{1}.{2}.{3}", _Octet1, _Octet2, _Octet3, _Octet4);
}