I'm using a ComboBox with property IsEditable=true created using the following code:
ComboBox buffer = new ComboBox()
{
BorderBrush = null,
Foreground = new SolidColorBrush(Colors.Black),
Background = null,
FontFamily = new FontFamily("Segoe UI Semilight"),
FontSize = 24,
IsEditable = true,
IsTextSearchEnabled = true,
IsTextSearchCaseSensitive = false,
StaysOpenOnEdit = true,
};
It is added in a WrapPanel in a ScrollViewer defined like this :
<ScrollViewer Margin="582,107,142,240"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Height="226" Width="357">
<Border Background="White"
CornerRadius="10"
BorderBrush="Black"
BorderThickness="1"
MouseDown="Border_MouseDown"
MouseLeave="Border_MouseLeave"
MouseUp="Border_MouseUp">
<WrapPanel x:Name="sourcesWrapPanel" Width="357"/>
</Border>
</ScrollViewer>
It works fine when selecting manually but writing will not work (pressing the keys does not input any text). The only thing that works is selecting an item using the mouse or the up/down arrows then deleting characters in it using backspace. What am I missing?
Take a look at the documentation for ComboBox.IsEditable:
I think you need to set ComboBox.IsReadOnly to false.
The e.Handled was set to true in the parent control so only the PreviewKeyDownhandler was executed for the child (ComboBox) which is why I could only delete text or paste it but not write any.
Related
How do I prevent the textbox from hiding the selected text highlight when the textbox loses focus? The following line worked for WPF
textBox1.IsInactiveSelectionHighlightEnabled = true;
but what is the equivalent for UWP?
You can set the SelectionHighlightColorWhenNotFocused property either in Xaml or via code. You can set it to any color you want, I just used binding to make sure it's the same color as the SelectionHighlightColor to make it easy.
<TextBox Style="{StaticResource TextBoxLightStyle}" Name="TextBoxMain"
AcceptsReturn="True"
SelectionHighlightColorWhenNotFocused="{Binding SelectionHighlightColor, ElementName=TextBoxMain, Mode=OneWay}">
</TextBox>
As I know there is no equivalent in UWP for that. One of possible work-around solutions could be to use some image to keep selection highlighted. Here is sample code:
XAML:
<Border BorderThickness="2" BorderBrush="{ThemeResource TextBoxBorderThemeBrush}" Height="164" Width="684">
<TextBox x:Name="textBox" TextWrapping="Wrap" Text="TextBox" BorderThickness="0,0,0,0"/>
</Border>
C#:
private async void TextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
// clear background
textBox.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 255, 255, 255)); ;
// render image
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(textBox);
// set background
textBox.Background = new ImageBrush()
{
ImageSource = renderTargetBitmap
};
}
In focus:
Not in focus:
p.s. I'm updating background on SelectionChanged event, but actually you can create image on that event and update only on LostFocus event. It should be more efficient.
I have a part of text which some of the words are formatted.
These text are listed in a ListBox. When user clicks ListBoxitem, I want to collect that selectedItem and take user to the other place. My problem is that I cant bind TextBlock with another instance of TextBlock. And that TextBlock has many inlines, which I want to show.
I have been trying this solution:
<ListBox Width="800" Name="foundedTextBlocksListBox" SelectionChanged="foundedTextBlocksListBox_SelectionChanged" Background="Transparent" ItemsSource="{Binding}" Grid.Row="2" Visibility="Visible" Height="Auto" HorizontalAlignment="Center">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel VerticalAlignment="Center" Orientation="Vertical">
<TextBlock x:Name="foundedTextBlocks" DataContext="{Binding Textblock}"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
After Binding to DataContext like this:
ObservableCollection<FoundedTextBlock> listOfFoundedTextBlockResults = new ObservableCollection<FoundedTextBlock>();
TextBlock textblock = new TextBlock();
while (blockString.IndexOf("<b>") != -1)
{
int startOfWord = blockString.IndexOf("<b>");
int endOfWord = blockString.IndexOf("</b>");
string text = blockString.Substring(0, startOfWord);
textblock.Inlines.Add(text);
string boldedWord = blockString.Substring(startOfWord + 3, endOfWord - startOfWord - 3);
textblock.Inlines.Add(new Run() { Text = boldedWord, FontWeight = FontWeights.Bold });
blockString = blockString.Substring(endOfWord + 4);
textblock.Inlines.Add(blockString);
}
textblock.Tag = dbInfo;
listOfFoundedTextBlockResults.Add(new FoundedTextBlock() { Textblock = textblock });
}
foundedTextBlocksListBox.DataContext = listOfFoundedTextBlockResults;
I can't see any ListBoxItems in ListBox. Is my Binding wrong or is this possible at all?
I managed before to get TextBlock.Text property to show but not the Inlines where are bolded text or any other Inlines after my first inline addition to TextBlock.
How I can solve this annoiyng problem? In short, I need to display many TextBlocks with formatted text...
FoundedTextBlock class has TextBlock textblock {get;set;} property
I'm saving to Tag property my class instance, so I could collect the information I need when SelectedValueChanged event occurs.
Maybe you should use a ContentPresenter instead of TextBlock in your XAML
Replace
<TextBlock x:Name="foundedTextBlocks" DataContext="{Binding Textblock}"></TextBlock>
with
<ContentPresenter Content="{Binding Textblock}" />
Please try it out ... the rest of your code is missing to provide a better answer.
For a TextBlock in XAML, you can do the following inside a DataTemplate:
<TextBlock Text="myTextBlock Text" VerticalAlignment="Center" Margin="0,0,5,0"
ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible"/>
But when I try to set ScrollViewer.HorizonalScrollBarVisibility, it doesn't seem to do anything.
DataTemplate textBlockTemplate = new DataTemplate();
FrameworkElementFactory textBlockElement = new FrameworkElementFactory(typeof(TextBlock));
Binding c1Binding = new Binding("myBindingValue") { Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged };
textBlockElement.SetBinding(TextBlock.TextProperty, c1Binding);
textBlockElement.SetValue(TextBlock.TextWrappingProperty, TextWrapping.Wrap);
textBlockElement.SetValue(TextBlock.HeightProperty, System.Convert.ToDouble(23));
textBlockElement.SetValue(ScrollViewer.CanContentScrollProperty, true);
textBlockElement.SetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollBarVisibility.Visible);
textBlockTemplate.VisualTree = textBlockElement;
templateColumn.CellTemplate = textBlockTemplate;
myDataGrid.Columns.Add(templateColumn);
I am trying to make a DataGrid Column that has a TextBlock that shows one line of text, but allows you to scroll up/down to see the rest of the textblock.
TextBlock doesn't have a ScrollViewer contained in it to set scrolling behavior on. You need to wrap it in a ScrollViewer on which you can set whatever you want. Contrast this to a ListBox, which does contain a ScrollViewer in its ControlTemplate so can take advantage of the attached properties.
I am programmatically creating a popup for an element in a WPF window and can't get rid of the black border:
var p = new Popup {
PlacementTarget = target,
IsOpen = true,
StaysOpen = false,
AllowsTransparency = true
};
// Add the popup content
p.Child = new Views.MapLocationInformation {DataContext = context};
The User control MapLocationInformation is defined in XAML like this:
<UserControl ...
mc:Ignorable="d"
Background="Transparent"
d:DesignHeight="65" d:DesignWidth="401">
<Border BorderThickness="1"
CornerRadius="5"
BorderBrush="{StaticResource ExpanderHeaderBorderGradient}"
Background="White"
Margin="0 0 8 8">
<Stackpanel> ... </Stackpanel>
</Border>
</UserControl>
I cannot find any combination of border, background fill and transparency setting which would render the black area transparent. Any idea?
Your Popup allows transparency but is not using a transparent background. Change to:
var p = new Popup {
PlacementTarget = target,
IsOpen = true,
StaysOpen = false,
AllowsTransparency = true,
Background = Brushes.Transparent
};
That should do the trick. Also, the reason the black bit is wider on the right and bottom is due to the Margin on your Border, which is actually kind of useless. I suggest you remove that too.
I just ran into the same problem. The problem appers to be, that when the Popup's IsOpen Property is to True too early, the transparency is not working properly.
My Solution was to move setting IsOpen to true from the contruction to the Loaded event of the Popup.
myPopup.Loaded += (sender, args) => { myPopup.IsOpen = true; };
This is caused by the Background property of MapLocationInformation. Just set the Background of your UserControl to null and AllowsTransparency to True to fix it, like this:
<UserControl ...
mc:Ignorable="d"
Background="{x:Null}"
AllowsTransparency="True"
#NikoR is right. But it is just the order of the properties.
You must set AllowsTransparency before IsOpen:
var popup = new Popup
{
AllowsTransparency = true,
IsOpen = true
};
In my case all I needed to add was AllowsTransparency = true for the Popup. I have a feeling Kent's answer is correct, and the inclusion of a nonexistent Background property there is not relevant because it is not needed.
I am creating Dynamic Rectangle and adding into StackPanel. I need to add text to each rectangle. How can I do that?
A Rectangle doesn't have any child content, so you will need to put both controls inside of another panel, such as a grid:
<Grid>
<Rectangle Stroke="Red" Fill="Blue"/>
<TextBlock>some text</TextBlock>
</Grid>
You can also use a Border control, which will take a single child and draw a rectangle around it:
<Border BorderBrush="Red" BorderThickness="1" Background="Blue">
<TextBlock>some text</TextBlock>
</Border>
You say "dynamic rectangle", so it sounds like you are doing this in code. The equivalent C# would look something like this:
var grid = new Grid();
grid.Children.Add(new Rectangle() { Stroke = Brushes.Red, Fill = Brushes.Blue });
grid.Children.Add(new TextBlock() { Text = "some text" });
panel.Children.Add(grid);
// or
panel.Children.Add(new Border()
{
BorderBrush = Brushes.Red,
BorderThickness = new Thickness(1),
Background = Brushes.Blue,
Child = new TextBlock() { Text = "some text" },
});
But if you want a dynamic list of rectangles, you should probably use an ItemsControl:
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Red" BorderThickness="1" Background="Blue">
<TextBlock Text="{Binding Text}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
If you set the DataContext to a list of objects, this XAML will create a Border with a TextBlock for each one with the text set to the Text property on the object.
First of all you can do this, but not by adding the control. And there is a very good reason to do this, for high speed hardware rendering. You can create a special brush from a UI element that caches itself in hardware and fill the rectangle with this hardware, and it is extremely fast. I will just show the code behind because it is the example I have offhand
Rectangle r = new Rectangle();
r.Stroke = Brushes.Blue;
r.StrokeThickness = 5;
r.SetValue(Grid.ColumnProperty, 1);
r.VerticalAlignment = VerticalAlignment.Top;
r.HorizontalAlignment = HorizontalAlignment.Left;
r.Margin = new Thickness(0);
r.Width = 200;
r.Height = 200;
r.RenderTransform = new TranslateTransform(100, 100);
TextBlock TB = new TextBlock();
TB.Text = "Some Text to fill";
// The next two magical lines create a special brush that contains a bitmap
// rendering of the UI element that can then be used like any other brush
// and it's in hardware and is almost the text book example for utilizing
// all hardware rending performances in WPF unleashed 4.5
BitmapCacheBrush bcb = new BitmapCacheBrush(TB);
r.Fill = bcb;
MyCanvas.Children.Add(r);
You need to add a textual control to your StackPanel, such as Label or TextBlock.