I have created a TextBox above a Path-Element (the Path Element draws a rectangular thing, which acts as the design of the textbox). Now I want to disable this TextBox with
valCon.ValueTextBox.IsEnabled = false;
This works so far. However, since I don't want the TextBox to have any Style (no Color, no Borders, etc.), but only a visible Text in it, I'm getting a small problem:
When the TextBox is disabled, it automatically receives a style which I can't get rid of. The Background changes to white, the Opacity changes to around 0.3 and Borders appear.
I can't seem to solve this problem by adding
valcon.ValueTextBox.Background = new SolidColorBrush(Colors.Transparent);
valcon.ValueTextBox.BorderBrush = new SolidColorBrush(Colors.Transparent);
etc.
It just seems to ignore this. Does anyone know a solution?
Greetings
Narakuvera
You need to take control over the template to achieve the same
here is a basic template for you with no border and no background TextBox
<TextBox Text="hello">
<TextBox.Template>
<ControlTemplate TargetType="TextBox">
<ScrollViewer Margin="0"
x:Name="PART_ContentHost" />
</ControlTemplate>
</TextBox.Template>
</TextBox>
you can choose to set IsEnabled="False" and it will still remain border less
Code behind approach
ControlTemplate ct = new ControlTemplate(typeof(TextBox));
FrameworkElementFactory sv = new FrameworkElementFactory(typeof(ScrollViewer));
sv.Name = "PART_ContentHost";
ct.VisualTree = sv;
textbox1.Template = ct;
WinRT code behind approach
string template = "<ControlTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" TargetType=\"TextBox\"><ScrollViewer Name=\"PART_ContentHost\" /></ControlTemplate>";
ControlTemplate сt = (ControlTemplate)XamlReader.Load(template);
textbox1.Template = сt;
Related
I am attempting to add an expander from code behind to an existing ListBox. The content that needs to be displayed in the header of the expander comes from a directory name which may or may not contain underscores. I want to preserve the directory name and not have the first underscore be interpreted as a keyboard shortcut.
I found this thread discussing how to do it in xaml and have tried to implement the same solution in code behind without any luck.
I also found this thread discussing how to create a data template from the code behind, but I can't get that to work either.
I have tried the following code snippets but either it won't compile or it just displays blanks for the expander headers:
String markup = String.Empty;
markup = "<TextBlock text=\"" + directory.Name + "\"/>";
ex.HeaderTemplate = new DataTemplate((DataTemplate)XamlReader.Load(markup));
.
ex.HeaderTemplate = new DataTemplate("TextBlock");
TextBlock tb = new TextBlock();
tb.Text = directory.Name;
ex.Header = tb;
you don't need to change HeaderTemplate to avoid underscore conversion into AccessKey.
add TextBlock into Expander.Header explicitly, and it will keep text unchanged.
<Expander>
<Expander.Header>
<TextBlock x:Name="ExpanderHeader"/>
</Expander.Header>
</Expander>
this way you don't need to create UI elements in c# code.
change header text in ExpanderHeader textBlock
ExpanderHeader.Text = directory.Name;
or bind it if there is a view model:
<TextBlock x:Name="ExpanderHeader" Text="{Binding Path=...}"/>
I currently have a class that inherits from Control and I give it a custom shape by setting its style to a style defined in the xaml resources:
<Style x:Key="ParameterStyle" TargetType="{x:Type local:ParameterUI}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ParameterUI}">
<Canvas>
<Ellipse
x:Name="component"
HorizontalAlignment="Left" Height="50"
Margin="0,0,0,50" Stroke="#FF8E8E9F"
VerticalAlignment="Top" Width="50"
StrokeThickness="1.5" Fill="#FF202020"/>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I was able to define all sorts of mouse events on this control and get it to behave as I want. Now, I want to dynamically add nested controls inside this control, and I want each one of those nested controls to have custom shapes, and mouse events etc, all defined at runtime. Almost none of the UI is static so its all defined at runtime. I tried adding controls, buttons as visual children, logical children, and nothing shows up in the UI. I don't even see anything in the live visual tree. What am I doing wrong here ? Should I be taking a different approach ? How can I access the Style > Setter.Value > ControlTemplate > Canvas at runtime to add more content to it ? Also, the content is different for each instance of the control.
I saw this post which asks a very similar question but the answer is a verbal description and I don't know how to implement this. I also found many solutions that write static UI in xaml but when I try to recreate that in C# it just doesn't work. I couldn't find any other examples on how to do this. Any help is appreciated, thanks!
You'll save yourself a lot of headache in future if you do things properly and use data-binding instead of manipulating the GUI elements directly, but if you insist...
You need to use the Visual Tree Helper to traverse the control in order to find the templated framework element. You may also may need to call ApplyTemplate first to make sure that your control has been templated and is ready to access:
yourTemplatedControl.ApplyTemplate();
var canvas = VisualTreeHelper.GetChild(yourTemplatedControl, 0) as Canvas;
var ellipse = new Ellipse();
ellipse.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
ellipse.VerticalAlignment = System.Windows.VerticalAlignment.Top;
ellipse.Width = 50;
ellipse.Height = 50;
ellipse.Margin = new Thickness(0, 0, 0, 50);
ellipse.Stroke = Brushes.Blue;
ellipse.StrokeThickness = 1.5;
ellipse.Fill = Brushes.Yellow;
canvas.Children.Add(ellipse);
In this code I've just assumed that the first element in the template would be a Canvas, in practice you might prefer to search the visual tree for your canvas element (see here and here for more info).
I am new to WPF, I wanted to display a window with multiple user controls.
example.xaml
<DockPanel>
<Border x:Name ="TopRegion" DockPanel.Dock = "top">
<local:userControl1/>
</Border>
<Border x:Name ="leftRegion" DockPanel.Dock = "left">
<local:userControl2/>
</Border>
</DockPanel>
The usercontrol1 and usercontrol2 are other views in the same project. I.e usercontrol1.xaml and usercontrol2.xaml.
Problem is that i need to change the usercontrol of leftRegion from usercontrol2 to usercontrol3 during run time i.e programatically.
How to achieve this in example.xaml.cs program.
You already named the Border leftRegion, so you could use this Border to set a new child like
leftRegion.Child = new userControl3();
programatically in code behind.
This means you are replacing the instance of userControl2 of the Border with a new instance of userControl3.
While this is a legitimate request, it crosses with the logic of XAML and data binding, so I would suggest an alternative way that will have the same effect for end-user but is more in the spirit of XAML.
The solution is simple - just have both controls in your XAML and switch their Visibility based on whether you need one or another control to be displayed.
I have created the following piece of code that gets executed when I press an existing button made with the editor
var test = new TextBlock();
test.Text = "meep!";
test.Margin = new Thickness(50, 50, 100, 100);
FrontPage.Children.Add(test);
the code itself is working but after the "meep!" has been added to the screen all buttons created by the editor stop working, how do I fix this?
I guess you are putting the Button element inside a Grid named FrontPage as follows, and invoke the above code snippet in button click event handle. Then after you clicking the button, the TextBlock will be added to the application view but the button cannot be clicked again.
<Grid x:Name="FrontPage" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button
x:Name="btnaddtext"
Margin="117,289,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="btnaddtext_Click"
Content="Button" />
</Grid>
The reason is that if you didn't set the size for the TextBlock, it will stretch to fill the Grid, so that the TextBlock will cover the Button element that inside the Grid and it will not be clickable. TextBlock may be glassy so that you can still see the Button but cannot access. If you change TextBlock to TextBox and update the background color you may see the effects.
You have many ways to resolve this, for example, set Height and Width for the TextBlock as follows:
var test = new TextBlock();
test.Text = "meep!";
test.Height = 100;
test.Width = 100;
test.Margin = new Thickness(50, 50, 100, 100);
FrontPage.Children.Add(test);
Or change a parent layout panel, for example, to a StackPanel.
<StackPanel x:Name="FrontPage" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Button
x:Name="btnaddtext"
Margin="117,289,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Click="btnaddtext_Click"
Content="Button" />
</StackPanel>
There're also other ways. To use which way depends on your requirements and the layout. More details about layout panel please reference layout panels.
I think you foget to add the TextBlock's algment.
You can try add the property to TextBlock and the code is below.
var test = new TextBlock()
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
test.Text = "meep!";
test.Margin = new Thickness(50, 50, 100, 100);
FrontPage.Children.Add(test);
But I think I cant care all what you mean and my code can work.
And you should know that TextBlock cant be edit. The TextBlock only can show the text.
I am using standard Visual Studio templates and I have a ItemsDetailPage that contains a FlipView with a RichTextBlock in its DataTemplate.
I want to set the RichTextBlock block to my custom Paragraphs generated in text. I think there is no way to bind RichTextBlocks Block in XAML so I am using code behind. In the Loaded event of RichTextBlock I set its Block, that works ok. But the problem is, the Loaded event gets called only once when the page is displayed. When I "flip" to another item, the selected item of the FlipView changes but the Loaded event does not get called again (I think this is ok).
I tried setting the RichTextBlock in the FlipViews SelectionChanged item but that does not work.
var ind = this.flipView.SelectedIndex;
var flipViewItem = this.flipView.ItemContainerGenerator.ContainerFromIndex(flipView.SelectedIndex);
if (flipViewItem != null)
{
var scroller = FindFirstElementInVisualTree<ScrollViewer>(flipViewItem);
var tb = scroller.FindDescendantByName("richTextColumns").FindDescendantByName("richTextBlock") as RichTextBlock;
SetRichContent(tb, (flipView.SelectedItem as ArticleViewModel).HtmlContent);
}
The SetRichContent gets called, sets the RichTextBlocks Blocks but visually they do not change and after a few flips, the whole app crashes without any additional information.
So my question is, how do I get my own code called on the RichTextBlock with each flip (seleced item change)?
You can bind rich text boxes. Make sure your data context is set properly. We need to see more code to make an appropriate answer.
<RichTextColumns>
<RichTextColumns.ColumnTemplate>
<DataTemplate>
<RichTextBlockOverflow Width="400" Margin="50,0,0,0"/>
</DataTemplate>
</RichTextColumns.ColumnTemplate>
<RichTextBlock Width="400">
<Paragraph>
<Run Text="{Binding Content}"/>
</Paragraph>
</RichTextBlock>
</RichTextColumns>