将URI绑定到文本框

本文关键字:文本 绑定 URI | 更新日期: 2023-09-27 17:50:57

我有一个类型为System.URI的属性,并且我将它绑定到一个文本框。这似乎工作得很好,除了如果我输入像https://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直接绑定到文本框?还是我要用一个"代理"?属性来保存字符串值。我想直接绑定到URI的原因是我有IDataError验证,即检查URI的有效性,这工作得很好。

将URI绑定到文本框

我实现了你的转换器,它工作了,虽然我没有使用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(尽管是无效的)。