2011-01-28 10 views
7

Quiero tener un recurso de cadena, que contiene un hipervínculo. Supongo que esto no es posible, a menos que tuviera 4 cadenas de recursos:WPF Resources.resx cadena con hipervínculo?

texto pre-hipervínculo hipervínculo href texto hipervínculo de texto Post-hipervínculo.

luego construir en el XAML a través de:

<StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Right"> 
    <TextBlock Grid.Column="1" Text="{x:Static p.Resources.PreHText}" /> 
    <Hyperlink Grid.Column="1" NavigateUri="{x:Static p.Resources.HHref}"> 
    <TextBlock Text="{x:Static p.Resources.HText}" /></Hyperlink></TextBlock> 
    <TextBlock Grid.Column="1" Text="{x:Static p.Resource.PostHText}" /> 
</StackPanel> 

Cuál es horrible, para muchas razones (Styling, no muy dinámica, etc, etc). Creando mi propio formato de renderizado y cadena, como "Envíe un correo electrónico a {[email protected]|the helpdesk} para obtener más ayuda". ¿Hay alguna otra forma de lograr esto? (No tiene que utilizar el archivo resources.resx)

Respuesta

1

Al final acabo de hacer mi propio control textblock para él (llamado Imaginitively AdvancedTextBlock):

public class AdvancedTextBlock : TextBlock { 
     new private String Text { get; set; } //prevent text from being set as overrides all I do here. 
     private String _FormattedText = String.Empty; 
     public String FormattedText { 
      get { return _FormattedText; } 
      set { _FormattedText = value; AssignInlines(); } 
     } 
     private static Regex TagRegex = new Regex(@"\{(?<href>[^\|]+)\|?(?<text>[^}]+)?}", RegexOptions.Compiled); 

     public AdvancedTextBlock() : base() { } 
     public AdvancedTextBlock(System.Windows.Documents.Inline inline) : base(inline) { } 

     public void AssignInlines(){ 
      this.Inlines.Clear(); 
      Collection<Hyperlink> hyperlinks = new Collection<Hyperlink>(); 
      Collection<String> replacements = new Collection<String>(); 
      MatchCollection mcHrefs = TagRegex.Matches(FormattedText); 
      foreach (Match m in mcHrefs) { 
       replacements.Add(m.Value); 
       Hyperlink hp = new Hyperlink(); 
       hp.NavigateUri = new Uri(m.Groups["href"].Value); 
       hp.Inlines.Add(m.Groups["text"].Success ? m.Groups["text"].Value : m.Groups["href"].Value); 
       hp.RequestNavigate += new RequestNavigateEventHandler(hp_RequestNavigate); 
       hyperlinks.Add(hp); 
      } 
      String[] sections = FormattedText.Split(replacements.ToArray(), StringSplitOptions.None); 
      hyperlinks.DefaultIfEmpty(null); 
      for (int i = 0, l = sections.Length; i < l; i++) { 
       this.Inlines.Add(sections.ElementAt(i)); 
       if (hyperlinks.ElementAtOrDefault(i) != null) { 
        this.Inlines.Add(hyperlinks[i]); 
       } 
      } 
     } 

     void hp_RequestNavigate(object sender, RequestNavigateEventArgs e) { 
      RequestNavigate(sender, e); 
     } 

     // 
     // Summary: 
     //  Occurs when navigation events are requested. 
     public event RequestNavigateEventHandler RequestNavigate; 
    } 

Las únicas dos cosas que no estoy muy contento con mi aplicación es que:

a) que tenía que cortar-ocultar la propiedad de texto existente, porque no sabía cómo evitar que la propiedad pueda reemplazar las cosas que hago

B) (relacionado con A) Tengo que llamar al AssignInlines cada vez que se establece el campo FormattedText (que solo debe admitirse una vez), pero esto es otra vez, hasta no saber cómo conectar el método que realmente hace el mostrar cosas (Esperando encontrar un evento PreRender, Render o similar, sin embargo no pude), así que si alguien sabe cómo hacerlo, sería increíble :).

-2

Aquí está mi solución:

<TextBlock x:Name="MyTextBlock" Grid.Column="1" Text="{x:Static resource:ResourceFile.Message}" Style="{StaticResource MyTextStyle}" > 
    <Hyperlink> 
      click here 
    </Hyperlink> 
</TextBlock> 
Cuestiones relacionadas