将URI绑定到文本框

时间:2015-05-27 16:17:00

标签: c# wpf xaml binding

我有一个System.URI类型的属性,我把它绑定到一个文本框。这似乎工作得很好,除非我输入类似http://stackexchange.com/的东西,否则我不会让我进入/因为我得到了:

System.Windows.Data Error: 7 : ConvertBack cannot convert value 'http://' (type 'String'). BindingExpression:Path=webURL; DataItem='ItemViewModel' (HashCode=66245186); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String') UriFormatException:'System.UriFormatException: Invalid URI: The hostname could not be parsed.
   at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
   at System.Uri..ctor(String uriString, UriKind uriKind)
   at System.UriTypeConverter.ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, Object value)
   at MS.Internal.Data.DefaultValueConverter.ConvertHelper(Object o, Type destinationType, DependencyObject targetElement, CultureInfo culture, Boolean isForward)
   at MS.Internal.Data.SourceDefaultValueConverter.ConvertBack(Object o, Type type, Object parameter, CultureInfo culture)
   at System.Windows.Data.BindingExpression.ConvertBackHelper(IValueConverter converter, Object value, Type sourceType, Object parameter, CultureInfo culture)'

然后我尝试使用转换器将URI转换为认为问题的字符串:

public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    Uri input = value as Uri;
    if (input == null) return String.Empty;
    else return input.ToString();
}

public override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    string input = value as string;
    if (String.IsNullOrEmpty(input)) return null;
    else return new Uri(input, UriKind.RelativeOrAbsolute);
}

这更糟糕,因为如果URI无效,这实际上就会爆炸。

有没有办法将URI直接绑定到文本框?或者我只需要使用"代理"我的viewmodel中的属性保存字符串值。我想直接绑定到URI的原因是我有IDataError验证,即检查URI的有效性,这非常有用。

1 个答案:

答案 0 :(得分:1)

我实现了您的转换器并且它有效,但我不必使用override关键字。

我的XAML是:

<Window.Resources>
    <Converter:UriToStringConverter x:Key="UriStringToConverter"/>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0"
             Margin="5"
             Text="{Binding Url, Converter={StaticResource UriStringToConverter}}" />
    <TextBlock Grid.Row="1"
               Margin="5"
               Text="{Binding Url, Converter={StaticResource UriStringToConverter}}"/>
</Grid>

并且Url属性定义为:

    private Uri url = new Uri("http://example.com");
    public Uri Url
    {
        get { return url; }
        set
        {
            url = value;
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Url"));
        }
    }

该类实现了INofifyPropertyChanged接口。

请注意,我必须使用有效的URL初始化Uri,否则会引发异常。即使我输入(例如)“test”,它也会成功地将其转换回Uri(尽管是无效的)。