2011-05-16 52 views
1

我試圖構建一個基本上是IPv4地址的文本框的UserControl。具有多個文本框的UserControl聚合成一個DependencyProperty

在UserControl中有4個文本框,TextBlock包含一個「。」。每個文本框之間:

<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稱爲ip地址上,我可以綁定到,或在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地址的字符串),並讓每個Octet在其自己的TextBox中顯示。然後,如果任何Octet文本框發生更改,則會更新IPAddress依賴項屬性。

這可能嗎?我以正確的方式思考這個問題嗎?

回答

1

有很多方法可以做到這一點。一個是簡單地爲八位創建私有屬性和文本框綁定到這些屬性,如:

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

編輯:

雙向綁定有點棘手,因爲您需要更改通知才能更新UI。我處理這個問題的方式可能是創建一個具有八位字節和IP地址屬性的視圖模型類,並實現INotifyPropertyChanged,然後在UserControl的構造函數中創建它的一個實例,並將所有UI控件綁定到屬性。這樣當視圖模型上的IPAddress被設置時,設置者可以解析該值,更新八位字節屬性,並且它們引發PropertyChanged並且UI被更新。

然後在UserControl,我會處理的視圖模型PropertyChanged,並設置在控制IPAddress1財產上視圖模型變化IPAddress依賴屬性。 (這聽起來並不奇怪)

您還需要編寫一個函數,將視圖模型的IPAddress屬性設置爲IPAddress依賴項屬性的值,並將該函數設置爲回調函數 註冊DP。

這樣的事件鏈將是:東西套在控制的IPAddress屬性 - >的DP回調將在視圖模型的IPAddress屬性 - >的IPAddress二傳手解析八位位組,並設置Octet屬性 - >的Octet性能提高PropertyChanged - >結合推動在UserControl所改變的值輸出到UI控件。走另一條路,它是:用戶輸入一個字節 - >字節的設置器IPAddress在視圖模型 - >用戶控制手柄PropertyChanged,並設置IPAddress依賴屬性。

+0

所以,如果我我的用戶的ip地址依賴屬性綁定到一些正確格式化字符串,怎麼辦八位得到更新? (雙向綁定): Scott 2011-05-16 18:20:24

+0

然後我認爲你需要實現一個視圖模型。看我的編輯。 – 2011-05-16 21:41:18

+0

哈...所以我試過所有的這些東西的第一次......這是做不到的。我後來發現在我的dp中有默認數據導致它在我綁定到與默認數據已經相同的數據時顯示爲空白:* public static readonly DependencyProperty IPAddressProperty = DependencyProperty.Register(「IPAddress」,typeof(字符串)的typeof(IPBOX),新UIPropertyMetadata( 「0.0.0.0」,新PropertyChangedCallback(IPAddressChanged))); *。當我刪除「0.0.0.0」,一切都開始工作。感謝您抽出寶貴時間看看並幫助我! – Scott 2011-05-16 22:34:25

相關問題