UserControl с несколькими TextBox'ами, которые объединяются в DependencyProperty - PullRequest
1 голос
/ 16 мая 2011

Я пытаюсь создать UserControl, который по сути является текстовым полем адреса IPv4.

В UserControl есть 4 текстовых поля, причем текстовый блок содержит один символ "." между каждым 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>

Я надеюсь, что у меня может быть DependencyProperty с именем IPAddress для элемента управления, к которому я могу привязаться, или для установки значения по умолчанию в XAML "123.123.123.123".

<local:IPBox IPAddress="123.123.123.123" />

Я думал, что мог бы использовать что-то вроде MultiBinding и 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('.');
    }
}

Но я считаю, что это будет противоположно тому, что я хочу. MultiValueConverter объединит несколько свойств бизнес-логики в одно свойство для привязки TextBox.

Вместо этого я хочу связать одно свойство бизнес-логики (строку, представляющую адрес IPv4) и сделать так, чтобы каждый октет отображался в своем собственном TextBox. Затем, если какой-либо из октетов TextBoxes изменится, свойство зависимостей IPAddress будет обновлено.

Возможно ли это? Правильно ли я думаю об этой проблеме?

1 Ответ

1 голос
/ 16 мая 2011

Есть много способов сделать это. Нужно просто создать личные свойства для октета и привязать текстовые поля к этим свойствам, например ::10000

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

Edit:

Двустороннее связывание немного сложно, потому что вам нужно уведомление об изменении для обновления пользовательского интерфейса. Вероятно, я бы решил создать класс модели представления со свойствами октета и IP-адреса и реализовать INotifyPropertyChanged, а затем создать его экземпляр в конструкторе UserControl и связать все элементы управления пользовательского интерфейса со свойствами. Таким образом, когда устанавливается IPAddress в модели представления, установщик может анализировать значение, обновлять свойства октета, и они вызывают PropertyChanged, и пользовательский интерфейс обновляется.

Затем в UserControl я бы обработал PropertyChanged в модели представления и установил свойство зависимости IPAddress для элемента управления , когда свойство IPAddress1 в представлении модель меняется. (Это не так странно, как кажется.)

Вам также понадобится написать функцию, которая устанавливает для свойства IPAddress модели представления значение свойства зависимости IPAddress, и установите эту функцию в качестве обратного вызова, когда вы зарегистрировать ДП.

Таким образом, цепочка событий будет: что-то устанавливает свойство IPAddress в элементе управления -> обратный вызов DP устанавливает свойство IPAddress в модели представления -> установщик IPAddress анализирует октеты и устанавливает Octet свойства -> повышение свойств Octet PropertyChanged -> привязка передает измененные значения в элементы управления пользовательского интерфейса в UserControl. Иначе говоря: пользователь вводит набор октетов -> наборов октетов IPAddress в модель представления -> пользовательский элемент управления обрабатывает PropertyChanged и устанавливает свойство зависимостей IPAddress.

...