Anyone have an idea of how to even approach this?
I dont have any code to present as I don`t have a clue where to start, thats why Im posting this.
My plan is to dynamically load a string array of some 7000 words over the WPF App WrapWindow with hidden background image. The text should be transparent to expose the image behind (something like Tag Cloud). I have attached link to the example which will help you to visualize the problem.
I have tried using ImageBrush but it does not support direct content (i.e. a string). I have also tried using Opacity Masks but without any success.
To give you an idea, below is the image and link to the similar unanswered topic but with an effect Im trying to achieve.
transparent text with opaque background
Any ideas are welcomed.
Thanks
OK, so this is what I have currently and what I was able to achieve with single hard coded string.
Simple xaml, image as background and WrapPanel which gets dynamically populated by the TEST STRING in form of a button.
<Grid>
<Image Source="/Images/test.jpg" Stretch="Fill"/>
<WrapPanel x:Name="WrapPan"/>
</Grid>
And just a draft copy of the code behind.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
LoadData();
}
string[] test = { "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",
"TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",
"TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",
"TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",
"TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",
"TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",
"TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",
"TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",
"TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING", "TEST STRING",};
private void LoadData()
{
for (int i = 0; i < test.Length; i++)
{
Button BtnWithName = new Button
{
Style = (Style)FindResource("MaterialDesignFlatButton"),
Content = test[i].ToString(),
Padding = new Thickness(0, 0, 5, 0),
Height = 12,
Command = DialogHost.OpenDialogCommand,
FontSize = 10,
Foreground = Brushes.White,
Opacity = 1,
FontFamily = new FontFamily("Arial Black"),
ToolTip = test[i].ToString(),
};
Button BtnClose = new Button
{
Content = "Close",
Command = DialogHost.CloseDialogCommand,
Width = 100
};
Grid myGrid = new Grid();
myGrid.Height = 200;
myGrid.Width = 200;
RowDefinition gridRow1 = new RowDefinition();
RowDefinition gridRow2 = new RowDefinition();
myGrid.RowDefinitions.Add(gridRow1);
myGrid.RowDefinitions.Add(gridRow2);
TextBlock textBlock = new TextBlock();
textBlock.HorizontalAlignment = HorizontalAlignment.Center;
textBlock.Text = test[i].ToString();
StackPanel sp = new StackPanel();
sp.HorizontalAlignment = HorizontalAlignment.Center;
sp.Children.Add(textBlock);
myGrid.Children.Add(sp);
Grid.SetRow(sp, 0);
myGrid.Children.Add(BtnClose);
Grid.SetRow(BtnClose, 1);
myGrid.VerticalAlignment = VerticalAlignment.Center;
BtnWithName.CommandParameter = myGrid;
WrapPan.Children.Add(BtnWithName);
}
}
}
And this gives me the output below:
Then, after some experimentation I have fund the way to apply image opacity mask with VisulaBrush set to TextBlock which give me the desired effect. Now the question remains of how I will dynamically do the same thing as above with an array of strings but with the effect as below?
<Image Source="/Images/test.jpg" Stretch="Fill">
<Image.Effect>
<BlurEffect Radius="0"/>
</Image.Effect>
<Image.OpacityMask>
<VisualBrush>
<VisualBrush.Visual >
<TextBlock Text="test" />
</VisualBrush.Visual>
</VisualBrush>
</Image.OpacityMask>
</Image>
BrushVisual can have only one Item so I placed the WrapPanel in MaterialDesign DialogHost. I can now populate the WrapPanel with my strings. The problem I have now is that whatever I do I cant control the Text size on my Button and the more buttons I put the image gets distorted and squeezed (image below) and stretches or compacts when Im resizing the window.
<Image Source="/Images/test.jpg" Stretch="Fill">
<Image.Effect>
<BlurEffect Radius="0"/>
</Image.Effect>
<Image.OpacityMask>
<VisualBrush >
<VisualBrush.Visual>
<materialDesign:DialogHost>
<WrapPanel x:Name="WrapPan"/>
</materialDesign:DialogHost>
</VisualBrush.Visual>
</VisualBrush>
</Image.OpacityMask>
</Image>




You could clip a canvas with the geometry of the text outline. Here is a class that outlines text as a shape.
Using it in xaml as normal
So if you had a canvas with a white background you can clip it with the inverse of your text path. To invert a clip create a path that combines the path geometry of the text with a rect of the same dimensions as the canvas. Use the combined geometry mode of "exclude".