|
Hi
I want to add hyperlink to a Textblock from model. Here is my code...
XAML:
<ItemsControl x:Name="Items" Style="{DynamicResource ItemsControlStyle}" />
<Style x:Key="ItemsControlStyle" TargetType="{x:Type ItemsControl}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Grid x:Name="grid">
-----------
<TextBlock Text="{Binding Text}" />
-----------
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
In xaml.cs:
Items.ItemsSource = ItemsData;
In Model
ItemsData.Add(Text = <some Value>);
This works fine and display the normal text. But I want to add hyperlink to the text from the model class. I dont want to change the xaml. So how could I add hyperlink to text from Model class?
Thanks in Advance,
|
|
|
|
|
Same reply as here...[^]
To put a hyperlink (which is formatted text) as the textblock content you'll need to use formatted text added to th TextBlock.Inlines property instead of the Text property (which is for plain text).
Maybe something like this (I'll let you work it into your model)...
Run r = new Run("link");
mytextblock.Inlines.Add(new Hyperlink(r));
Mark Salsbery
|
|
|
|
|
Mark,
I can't access the textblock in model and also the same textblock is used to show other data and for other data I don't want to show the hyperlink.
I want to show hyperlink for some of the data. So I have to add hyperlink in Model to the text but not for the textblock. How could I do this?
Thanks,
|
|
|
|
|
TextBlocks only support text unless you add a hyperlink run. They don't know how to render hyperlinks by themselves. Unfortunately, the Inlines collection is not bindable. If you *really* want to do this in a MVVM way, you'd need to derive a class from TextBlock, i.e. TextBlockEx and add a bindable version of the Inlines property (i.e.) InlinesEx or whatever and every time Inlines or InlinesEx changes, you sync up the other one. I've done something similiar with ListView.SelectedItems, so I know the "theory" works . This IMO, is the method to keep everything as legit MVVM as possible.
|
|
|
|
|
Hi All,
I have following code in silverlight, I want to set max width for the StackPanel dynamically in xaml, but its not showing anything, means the width or max width value it is getting is "0". Basically I want to set the maxwidth of xaml to wrap the text inside the textblock
Foloowing is the Silverlight user control xaml:
<UserControl x:Class="TextBlockLayoutTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:converters="clr-namespace:ConvertersSilverlightClassLibrary;assembly=ConvertersSilverlightClassLibrary"
mc:Ignorable="d" x:Name="testUC">
<UserControl.Resources>
<converters:PercentageConverter x:Key="PercentageConverter"/>
</UserControl.Resources>
<Grid x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="gridCol1" Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Grid.Row="0" Grid.Column="0"
MaxWidth="{Binding ElementName=grid, Path=ActualWidth}">
<TextBlock TextWrapping="Wrap" >
test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test
</TextBlock>
</StackPanel>
</Grid>
</UserControl>
public class PercentageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double d = System.Convert.ToDouble(value);
d = System.Convert.ToDouble(parameter);
return System.Convert.ToDouble(value) * System.Convert.ToDouble(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
I tried to do the same using converters too, I binded my TextBlock width property with this PercentageConverter class still, the convert method is returning 0 so the textblock is becoming invisible. I tried in all the ways to wrap the text in side the textblock and show it accordning to the maxwidth of stack panel. In anyways its not becoming possible to wrap the text. We are implementing MVVM and Prism so we dont to implement code behind.
Can anybody please help me achieving this without using the code behind.
Thanks in advance.
Thanks & Regards,
Abdul Aleem Mohammad
St Louis MO - USA
|
|
|
|
|
Your XAML shows no place you are actually trying to constrain the size to, so I assume you want the StackPanel constrained to the size of the UserControl. If that's the case then just the grid with the stackpanel in it will do that without your binding attempt...
<Grid x:Name="grid">
<StackPanel Orientation="Vertical" >
<TextBlock TextWrapping="Wrap" >
test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test test
</TextBlock>
</StackPanel>
</Grid>
What do you really want to constrain the stackpanel size to?
Mark Salsbery
|
|
|
|
|
I think everything is working "as expected" . You just expected the wrong outcome . I suspect the layout cycle is resulting in your TextBlock wrapping to a width of 0.
I'd get rid of the column definition, get rid of MaxWidth on StackPanel and add something like this to TextBlock:
Width={Binding ElementName=grid, Path=ActualWidth}
That way you are sizing the TextBlock to the width of the grid and it'll wrap to that width.
|
|
|
|
|
Hi,
No use, its not working still. Why MS has created this binding IDK but that never ever works for me at all.
Why did MS has created this complex I dont know.
Thanks & Regards,
Abdul Aleem Mohammad
St Louis MO - USA
|
|
|
|
|
I have an application which, while displaying a splash screen, checks for the presence of several files required for the proper running of the main window. If a file is not found the filename is passed to a method and the following should happen:
> progressbar colour changed to indicate an error
> status message(normally used to tell the user what the app is doing) tells the user that something has gone wrong
> a messagebox is displayed, giving the user the exact name of the required file that is missing.
The problem I'm having is that if a file is found to be missing, the messagebox displays but the splash never does. Is there a way to do it so that the messagebox appears over the top of the window ?
modified 4-Nov-11 13:47pm.
|
|
|
|
|
I think what is happening is that everything is running on the UI thread, and so locking up the splash screen. You should try running the file search on a separate thread(BackgroundWorker) or in a new task if you are using .Net 4.0.
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
Hmm haven't used either options before, guess I've got some googling to do.
|
|
|
|
|
Sacha Barber wrote an excellent series of articles on the Task Parallel Library . Here[^] is the first one to start you off. Have fun!
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
I've got my task set up, now to stop it complaining that the progressbar is owned by another thread :/
*Edit* Looks like I'm going to half to split my foreach which goes through a string array and checks each required file into seperate tasks for each one. All this effort for something that should be so simple
modified 4-Nov-11 13:15pm.
|
|
|
|
|
All UI objects are owned by the UI thread. You can't access them from another thread. This is by design. You need to use the thread dispatcher. Something like:
Dispatcher.Invoke(DispatcherPriority.Input, new Action(() =>
{
// do stuff in here
}));
|
|
|
|
|
Thanks, got it sorted. Now to figure out why the whole app dies if fluent.dll (from http://fluent.codeplex.com) isn't there when only the main window needs it and isn't run until the splash screen tells it to.
*Edit* Was setting default theme in app.xaml, moved that and everthings fine. Thanks guys !
modified 4-Nov-11 13:46pm.
|
|
|
|
|
Glad you got it sorted.
When I was a coder, we worked on algorithms. Today, we memorize APIs for countless libraries — those libraries have the algorithms - Eric Allman
|
|
|
|
|
Please can anyone explain
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
what is this xmlns:x? why it use?
|
|
|
|
|
"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
The relationship between these declarations is that the x: prefix mapping supports the intrinsics that are part of the XAML language definition, and WPF is one implementation that uses XAML as a language and defines a vocabulary of its objects for XAML. Because the WPF vocabulary's usages will be far more common than the XAML intrinsics usages, the WPF vocabulary is mapped as the default.
The x: prefix convention for mapping the XAML language intrinsics support is followed by project templates, sample code, and the documentation of language features within this SDK."
I have posted this from here[^].
|
|
|
|
|
I cannot seem to find what I'm looking for....
I need to provide a grid with 2 columns: Item and Quantity.
In the Item column I want to have an editable combobox so that the user can pick an item from the list or type something in. The value they type in does not have to be the combo's data collection.
I'm not sure how to do this so I don't know what to search for. Anyone done this? Got an example?
Many thanks
Everything makes sense in someone's mind
|
|
|
|
|
Sounds like you want a PropertyGrid to me. Thats exactly what it does.
|
|
|
|
|
Ok, I've been working with this for a while and I'm not gtting it. This post is a bit long but explains things better than my first post.
I have a Query view in my app. The user can type in any search terms they want. In this screenshot I entered Item1 - Item5.
www.maroisconsulting.com/image/Query1.png[^]
When the user clicks the Apply button, what I want to happen is to hide the textbox and show the grid. Both are on the view. The textbox is initially visible and the grid is initially hidden.
The Apply method converts the search terms into a list of objects:
private void apply()
{
string[] temp = SearchTerms.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
var temp2 = (from s in temp
where s != string.Empty
select new SearchItemModel
{
SearchTerm = s,
Quantity = 1
}).ToList();
SearchItems = new ObservableCollection<SearchItemModel>(temp2);
GridVisible = true;
TextAreaVisible = false;
}
There are 2 columns on the grid. The first column is an editable combobox. It's source of data is a list of project names stored in a collection called 'BOMs' (Bills of Materials), something like
Project A4472A
BOM Project B2215B
Some Other BOM
The user should then be able to either type in any text to search on, or select a BOM project name from the combox box.
Here's the relevant XAML:
<DataGrid x:Name="grdItems"
Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="2"
AutoGenerateColumns="False"
ItemsSource="{Binding SearchItems}"
Visibility="{Binding GridVisible, Converter={StaticResource visibilityConverter}}"
Margin="5">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Search Terms"
Width="*">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Height="22"
IsEditable="True"
ItemsSource="{Binding BOMs}"
SelectedItem="{Binding SelectedBOMItem}"></ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Quantity"
Binding="{Binding Quantity}"
Width="100">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
After the Apply method runs, I get this: http://www.maroisconsulting.com/image/Query2.png[^]
What I would like to get is this (mocked up):
http://www.maroisconsulting.com/image/Query3.png[^]
Hope this made sense. Any thoughts on how to do this?
[UPDATE]
The Output window shows 2 errors:
"BindingExpression path error: 'BOMs' property not found on 'object' ''SearchItemModel' ("
"BindingExpression path error: 'SelectedBOMItem' property not found on 'object' ''SearchItemModel'"
Everything makes sense in someone's mind
|
|
|
|
|
Ah... ignore my suggestion of a property grid then since that'll only let you edit the right hand side.
Are the 'BOMs' and 'SelectedBOMItem' properties actually public properties in SearchItemModel? Seems like WPF is resolving to the proper DataContext (which I initially thought was the issue when I saw your XAML).
Are you sure that XAML you posted is EXACTLY the XAML you had when you got those error messages? Because if it is, it doesn't make sense. If BOMs and SelectedBOMItem are public props in SearchItemModel, they should be resolved since WPF seems to be looking at the right DataContext judging by those errors.
|
|
|
|
|
BOMs is a collection on the VM, and SelectedBOMItem is a property on the VM.
What I think is happening is since the grid is bound to a collection of SearchItems models, the combo thinks the BOMs and SelectedBOMItem object are on that model. I'm not sure, but that's what I got out of those messages. And, assuming thats the problem, I'm not sure how to tell the combo to look on the DataContext, not the SearchItems.
Everything makes sense in someone's mind
|
|
|
|
|
Ok, you confused me with your terminology / naming ... the problem is just as I originally suspected. The combobox is looking at the datacontext of the grid, not the VM. You can do something like (assuming your window has a name using the Name="myWindow" tag)...
<ComboBox DataContext={Binding ElementName=myWindow, Path=DataContext} ...
|
|
|
|
|
Ok, I see where you're going. The problem now is, these controls are inside a user control which is inside the main window.
The user control is named QueryView, and its VM is QueryViewModel, so I tried:
<DataGrid x:Name="grdItems"
Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="2"
AutoGenerateColumns="False"
ItemsSource="{Binding SearchItems}"
Visibility="{Binding GridVisible, Converter={StaticResource visibilityConverter}}"
Margin="5">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Search Terms"
Width="*">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Height="22"
DataContext="{Binding ElementName=QueryViewModel, Path=DataContext}"
IsEditable="True"
ItemsSource="{Binding BOMs}"
SelectedItem="{Binding SelectedBOMItem}"></ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Quantity"
Binding="{Binding Quantity}"
Width="100">
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
But I get a binding error in the output window. If I understand what you're trying here, you're telling the combo to get it's data from some other datacontext? The question is, how to tell it about the QueryViewModel that's inside the MainWindowViewModel.
Everything makes sense in someone's mind
|
|
|
|