UserControl con múltiples TextBoxes 'que se agregan a DependencyProperty

Estoy tratando de construir un UserControl que sea esencialmente un 'cuadro de texto' de dirección IPv4.

En UserControl hay 4 TextBoxes, con un TextBlock que contiene un solo "." entre cada TextBox:

<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>

Mi esperanza es poder tener un DependencyProperty llamado IPAddress en el control al que puedo enlazar, o establecer un valor predeterminado en XAML "123.123.123.123".

<local:IPBox IPAddress="123.123.123.123" />

Pensé que podría usar algo como MultiBinding y un IMultiValueConverter:

public class IPAddressConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return String.Format("{0}.{1}.{2}.{3}", values[0], values[1], values[2], values[3]);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((string)value).Split('.');
    }
}

Pero creo que eso sería lo contrario de lo que quiero. Un MultiValueConverter fusionaría varias propiedades de lógica empresarial en una sola propiedad para que un TextBox se vincule.

En su lugar, quiero vincular una sola propiedad de lógica empresarial (una cadena que representa una dirección IPv4) y hacer que cada octeto aparezca en su propio TextBox. Luego, si cambia alguno de los Octet TextBoxes, se actualizará la propiedad de dependencia IPAddress.

es posible? ¿Estoy pensando en este problema de la manera correcta?

preguntado el 16 de mayo de 11 a las 17:05

1 Respuestas

Hay muchas formas de hacer esto. Uno es simplemente crear propiedades privadas para el octeto y vincular los cuadros de texto a esas propiedades, por ejemplo:

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

y luego implementar setters que actualicen la propiedad de dependencia:

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);
}

Edit:

El enlace bidireccional es un poco complicado porque necesita una notificación de cambio para actualizar la interfaz de usuario. La forma en que manejaría esto, probablemente, es crear una clase de modelo de vista que tenga propiedades e implementaciones de octetos y direcciones IP INotifyPropertyChanged, luego cree una instancia en el constructor de UserControl y vincule todos los controles de IU a las propiedades. De esa manera cuando el IPAddress en el modelo de vista que se establece, el definidor puede analizar el valor, actualizar las propiedades del octeto y aumentar PropertyChanged y la interfaz de usuario se actualiza.

Entonces en el UserControlYo manejaría PropertyChanged en el modelo de vista y establezca el IPAddress propiedad de dependencia en el control cuando IPAddress1 propiedad en el ver modelo cambios. (Eso no es tan extraño como parece).

También necesitará escribir una función que establezca el modelo de vista IPAddress propiedad al valor de la IPAddress propiedad de dependencia, y establezca esa función como una devolución de llamada cuando registre el DP.

Entonces la cadena de eventos será: algo establece el IPAddress propiedad en el control -> la devolución de llamada DP establece el IPAddress propiedad en el modelo de vista -> el IPAddress setter analiza los octetos y establece el Octet propiedades -> el Octet propiedades aumentan PropertyChanged -> el enlace empuja los valores cambiados a los controles de la interfaz de usuario en su UserControl. Yendo hacia el otro lado, es: el usuario ingresa un octeto -> conjuntos de establecedores de octetos IPAddress en el modelo de vista -> controles de usuario PropertyChanged y establece el IPAddress propiedad de dependencia.

contestado el 17 de mayo de 11 a las 01:05

Entonces, si vinculo la propiedad de dependencia IPAddress de mi UserControl a alguna cadena con el formato correcto, ¿cómo se actualizan los octetos? (enlace bidireccional): - Scott

Entonces creo que necesitas implementar un modelo de vista. Ver mi edición. - Robert Rossney

Ja ... así que probé todas estas cosas la primera vez ... y simplemente no funcionó. Más tarde descubrí que tener datos predeterminados en mi dp hacía que aparecieran en blanco cuando me enlacé a datos que ya tenían el mismo valor que los datos predeterminados: public static readonly DependencyProperty IPAddressProperty = DependencyProperty.Register ("IPAddress", typeof (cadena), typeof (IPBox), nuevo UIPropertyMetadata ("0.0.0.0", nuevo PropertyChangedCallback (IPAddressChanged)));. Tan pronto como eliminé "0.0.0.0", todo comenzó a funcionar. ¡Gracias por tomarse el tiempo de ver esto y ayudarme! - Scott

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.