Unable to get emoji properly in RichTextBox - wpf

I am trying for binding the emoji to the rich textbox with an extended tool kit. I am able to do it but the emoji is displaying differently for the text box. I am getting it ass follows:
I am binding the value as following:
Uri uri = new Uri(ApplicationContext.Emojis[emote].ToString(),
UriKind.RelativeOrAbsolute);
BitmapImage source = new BitmapImage();
source.BeginInit();
source.UriSource = uri;
source.DecodePixelHeight = 25;
source.DecodePixelWidth = 25;
source.EndInit();
if (IsNullOrEmpty(MessageText.Text))
_contactsViewModel.TypedMessage = " ";
else if (!dataObjectToSend.Contains(MessageText.Text?.Trim('\r', '\n')))
dataObjectToSend.Add(MessageText.Text);
dataObject.SetImage(source);
dataObjectToSend.Add(selectedBindingContext.text.ToString());
Clipboard.SetDataObject(dataObject);
TextPointer caretPos = MessageText.CaretPosition;
caretPos = caretPos.DocumentEnd;
MessageText.CaretPosition = caretPos;
MessageText.Paste();
and my Textbox is
<toolkit:RichTextBox Text="{Binding TypedMessage,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
x:Name="MessageText"
Grid.Column="1"
BorderThickness="0"
BorderBrush="Transparent"
AcceptsReturn="True"
Foreground="Black"
FontSize="16"
Margin="0,2,2,2"
VerticalContentAlignment="Center"
VerticalAlignment="Center"
KeyUp="OnTypingMessage"
HorizontalContentAlignment="Left"
LostFocus="MessageText_OnLostFocus"
SpellCheck.IsEnabled="true">
What I want is to display the emoji in richTextBox as
Can some help me to achieve this, please.

Related

WPF ScrollViewer not working in Grid programmatically populated

I have this situation in xaml
<StackPanel Orientation="Vertical" Margin="5" Background="AliceBlue" Height="370">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid Name="DescriptionsGrid" MinHeight="0" MaxHeight="370" ScrollViewer.CanContentScroll="True"></Grid>
</ScrollViewer>
</StackPanel>
and I'm filling the Grid with the following
DescriptionsGrid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
TextBlock textBlock = new TextBlock { Text = description, TextWrapping = TextWrapping.WrapWithOverflow };
Label label = new Label { Content = textBlock, Foreground = new SolidColorBrush(Colors.Blue) };
label.MouseLeftButtonDown += new MouseButtonEventHandler(LoadXML);
DescriptionsGrid.Children.Add(label);
Grid.SetRow(DescriptionsGrid.Children[DescriptionsGrid.Children.Count - 1], description_counter);
description_counter++;
I can't define rows height as the description may be long enought to wrap the text to new line.
The scrollbar does not appears and new elements go hidden down below.
Any idea?
Following the suggestion of #Clemens I rewrote the code, and found that the mistake was in the XML.
To populate the grid
foreach (HostMessages hostMessage in hostMessagesList)
{
Label message = new Label
{
Content = new TextBlock {
Text = hostMessage.Description,
TextWrapping = TextWrapping.WrapWithOverflow
},
Foreground = new SolidColorBrush(Colors.Blue),
Cursor = Cursors.Hand
};
message.MouseLeftButtonDown += new MouseButtonEventHandler(LoadXML);
itemsControl.Items.Add(message);
}
The XML is as follows
<DockPanel Grid.Row="1" Margin="5" Background="AliceBlue" Height="370">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="370">
<ItemsControl Name="itemsControl"></ItemsControl>
</ScrollViewer>
</DockPanel>
The mistake was assigning a MaxHeight="370" to the Grid and none to the ScrollViewer.

Databinding Progress Bar Not Binding

I searched a lot for the solution to this, but can't seem to figure it out. (Just saying, this will be a long post)
Preface: This is NOT MVVM
Problem: I have a progress bar. I am currently trying to bind a public double to it from within the xaml's .cs file. However, whenever I use value's bind function, it never works, resulting in iNotifyPropertyChanged not working, etc. etc....
The variable it is bound to serves the purpose of updating the progress bar value. The way that is completed is by setting the value in a separate for loop in another method/class. The value is set by a simple equation. 100 divided by the length of a list, multiplied by the for loops counter. This gives us a real number that can be put into the progress bar value. (code below)
Binder.daWindow.progUpdate = ((100.00 / databaseTables.Length) * dbTIndex);
I know this can be completed by threading (or whatever), but I would appreciate answers specifically for how this might be done by binding (unless it's impossible, then forget what I just said).
XAML:
<Window x:Name="DateWindow1" x:Class="WpfApp1.DateWindow"
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:local="clr-namespace:WpfApp1"
xmlns:Main="using:DateWindow"
mc:Ignorable="d"
Title="Change Dates" Height="232.667" Width="462" Background="#FF2B2B2B" ResizeMode="NoResize">
<Grid>
<TextBox x:Name="DayChangeTextBox" HorizontalAlignment="Left" Height="30" Margin="176,45,0,0" TextWrapping="Wrap" Text="##" VerticalAlignment="Top" Width="58" FontSize="14" TextAlignment="Center" AcceptsReturn="False" AcceptsTab="False" GotFocus="DayChangeTextBox_GotFocus" LostFocus="DayChangeTextBox_LostFocus" BorderThickness="1" BorderBrush="Black" OpacityMask="Black" Background="#FFFDFDFD"/>
<Label Content="Days" HorizontalAlignment="Left" Margin="239,45,0,0" VerticalAlignment="Top" Width="42" FontSize="14" FontFamily="Microsoft YaHei UI" Height="30" Foreground="White"/>
<Label Content="Move Dates Forward:" HorizontalAlignment="Left" Margin="23,45,0,0" VerticalAlignment="Top" Width="144" FontSize="14" FontFamily="Microsoft JhengHei UI Light" Height="30" Foreground="White"/>
<Button x:Name="ChangeDatesButton" Content="Change Dates" HorizontalAlignment="Left" Margin="303,45,0,0" VerticalAlignment="Top" Width="143" Height="30" BorderThickness="1,1,2,3" BorderBrush="#FF474747" Click="ChangeDatesButton_Click" FontFamily="Microsoft YaHei UI" Background="#FFE6E6E6"/>
<Label x:Name="serverLabel" Content="Label" HorizontalAlignment="Left" Margin="10,73,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5" Width="5" Height="15" Visibility="Hidden"/>
<Label x:Name="databaseLabel" Content="Label" HorizontalAlignment="Left" Margin="20,73,0,0" VerticalAlignment="Top" Width="3" Visibility="Hidden" Height="15"/>
<Button x:Name="RevertToDefaultButton" Content="Revert to Backup" Margin="23,164,0,0" VerticalAlignment="Top" Height="30" Background="#FFE6E6E6" BorderBrush="#FF474747" BorderThickness="1,1,2,3" Click="RevertToDefaultButton_Click" FontFamily="Microsoft JhengHei UI" HorizontalAlignment="Left" Width="143"/>
<Button x:Name="OverwriteDefaultButton" Content="Backup Database" Margin="23,128,0,0" VerticalAlignment="Top" Height="30" BorderBrush="#FF474747" BorderThickness="1,1,2,3" Click="OverwriteDefaultButton_Click" FontFamily="Microsoft JhengHei UI" HorizontalAlignment="Left" Width="143" Background="#FFE6E6E6" />
<Button x:Name="CloseButton" Content="Close" Margin="0,164,10,0" VerticalAlignment="Top" Height="30" BorderBrush="#FF474747" BorderThickness="1,1,2,3" FontFamily="Microsoft JhengHei UI" Width="60" Click="CloseButton_Click" HorizontalAlignment="Right" Background="#FFE6E6E6" />
<Label x:Name="RevertBackupLabel" Content="Backup or Revert Database:" HorizontalAlignment="Left" Margin="12,93,0,0" VerticalAlignment="Top" Foreground="White" FontFamily="Microsoft JhengHei UI" FontWeight="Bold" FontSize="16"/>
<Label x:Name="DatesLabel" Content="Change Dates in Database:" Margin="12,10,0,0" Foreground="White" FontFamily="Microsoft JhengHei UI" FontWeight="Bold" FontSize="16" HorizontalAlignment="Left" Width="216" Height="30" VerticalAlignment="Top"/>
<ProgressBar HorizontalAlignment="Left" Height="13" Margin="303,80,0,0" VerticalAlignment="Top" Width="143" Name="pbStatus" Value="{Binding local.progUpdate, UpdateSourceTrigger=PropertyChanged}" Maximum="{Binding mx}" Minimum="{Binding mn}" LargeChange="0.01"/>
</Grid>
XAML CS Portion:
public static class Binder
{
public static DateWindow daWindow;
}
public partial class DateWindow : Window, INotifyPropertyChanged
{
private double _progUpdate;
public double progUpdate
{
get { return _progUpdate; }
set
{
_progUpdate = value;
if (PropertyChanged != null)
{
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(nameof(progUpdate)));
}
}
}
public double mx = 100;
public double mn = 0;
public event PropertyChangedEventHandler PropertyChanged;
public DateWindow()
{
InitializeComponent();
Binder.daWindow = this;
ChangeDateInDatabase ChangeDate = new ChangeDateInDatabase();
progUpdate = 25; // This is there so we can test the variable without going through the whole program.
}
private void ChangeDatesButton_Click(object sender, RoutedEventArgs e)
{
ChangeDateInDatabase ChangeDate = new ChangeDateInDatabase();
var result = MessageBox.Show("Are you sure you would like to change dates for " + Globals.selectedDatabase + " from server " + Globals.main.ServerComboBox.Text + "?", "Change Dates?", MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
if (Globals.main.ServerComboBox.Text != "" && Globals.selectedDatabase != "" && FindDatabaseAndServer.Connector(Globals.main.ServerComboBox.Text, Globals.selectedDatabase) && result == MessageBoxResult.Yes)
{
try
{
long.Parse(DayChangeTextBox.Text);
ChangeDate.ChangeDates(this);
//ChangeDateInDatabase.ChangeDates(this);
}
catch
{
MessageBox.Show($"Invalid number {DayChangeTextBox.Text}, please enter a valid number.", "ERROR", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
}
(CLICK function serves the purpose of calling a method for the program. Inside the method, its main loop, which determines the methods completion, contains the variable desired to be bound with a defining equation for its value)
Method Containing Said Loop:
for (int dbTIndex = 0; dbTIndex < databaseTables.Length; dbTIndex++)
{
string[] dateColumns = new string[0];
string columnSelectQuery = "SELECT DATA_TYPE, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '" + databaseTables[dbTIndex].ToString() + "' AND COLUMN_NAME LIKE '_%'";
using (SqlConnection connection2 = new SqlConnection(connectionString))
{
SqlCommand command2 = new SqlCommand(columnSelectQuery, connection2);
connection2.Open();
SqlDataReader reader2 = command2.ExecuteReader();
int y = 0;
while (reader2.Read())
{
if (reader2[0].ToString() == "datetime")
{
Array.Resize(ref dateColumns, dateColumns.Length + 1);
dateColumns[y] = reader2[1].ToString();
y++;
}
}
}
for (var dtColIndex = 0; dtColIndex < dateColumns.Length; dtColIndex++)
{
string addDatesQuery = "UPDATE " + databaseTables[dbTIndex] + " SET " + dateColumns[dtColIndex] + " = DATEADD(dd," + Convert.ToInt32(date.DayChangeTextBox.Text) + "," + dateColumns[dtColIndex] + ") WHERE " + dateColumns[dtColIndex] + " IS NOT NULL";
using (SqlConnection connection3 = new SqlConnection(connectionString))
{
SqlCommand command3 = new SqlCommand(addDatesQuery, connection3);
connection3.Open();
command3.ExecuteNonQuery();
}
}
//vvvvv VARIABLE THAT NEEDS TO BE BOUND vvvvvvv
Binder.daWindow.progUpdate = ((100.00 / databaseTables.Length) * dbTIndex);
}
(There is obviously more code to this part, which I can provide if needed)
Thanks in advance!
EDIT:
For the XAML, local.progUpdate is not the only thing I have tried. I've done path, progUpdate by itself, etc.
Your ProgressBar's first binding makes no sense: {Binding local.progUpdate, UpdateSourceTrigger=PropertyChanged}. You're not specifying a source, and there's no DataContext assigned anywhere, so the binding won't evaluate to anything because the path is meaningless. Because the property is on the window itself, you can just assign the window's data context to itself.
// DateWindow.xaml.cs
public DateWindow()
{
InitializeComponent();
DataContext = this;
...
}
<!-- DateWindow.xaml -->
<ProgressBar Value="{Binding progUpdate, Mode=OneWay}" ... />
Your other bindings will require mx and mn to be properties rather than fields.

Cannot modify the logical children for this node at this time because a tree walk is in progress

I have two wpf tool kit charts one is pie chart and second bar series
i have method which i call only on form load
chartGuest.DataContext = null;
List<KeyValuePair<string, int>> valueList = new List<KeyValuePair<string, int>>();
HProDataContext db = new HProDataContext();
var _RoomTypes = (from d in db.roomtypes select d.roomtype1).ToList();
var _RoomTypeID = (from d in db.roomtypes select d.id).ToList();
int count = 0;
for (int i = 0; i < _RoomTypeID.Count; i++)
{
count = Convert.ToInt32((from d in db.actions where d.room.roomtypeid == _RoomTypeID[i] select d.id).Count());
valueList.Add(new KeyValuePair<string, int>(_RoomTypes[i], count));
}
chartGuest.DataContext = valueList;
It gaves such error : Cannot modify the logical children for this node at this time because a tree walk is in progress.
The same code works great on pie series chart.
This is my charts:
<charting:Chart x:Name="chartRoomType" Width="402" Height="255" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="15,275,0,0">
<charting:Chart.Series>
<charting:PieSeries ItemsSource="{Binding}" DependentValuePath="Value" IndependentValuePath="Key" Title="Room Types" IsSelectionEnabled="True" />
</charting:Chart.Series>
</charting:Chart>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="314,292,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<TextBlock Height="23" HorizontalAlignment="Left" Margin="28,296,0,0" Name="textBlock4" Text="Room Types" VerticalAlignment="Top" />
<charting:Chart x:Name="chartGuest" Height="269" VerticalAlignment="Top" Margin="6,0" Title="Guests">
<charting:Chart.Series>
<charting:BarSeries ItemsSource="{Binding}" DependentValuePath="Value" IndependentValuePath="Key" Title="Room Types" IsSelectionEnabled="True" />
</charting:Chart.Series>
</charting:Chart>
Can anyone help me?
P.s. i found this question but it was unhelpful
What does Cannot modify the logical children for this node at this time because a tree walk is in progress mean?
Use DataPointSeries.ItemsSource to bind to the data context.
Assuming that this is XAML of your your window panel that has the datagrid and charting control sharing a common list as ItemsSource..
<StackPanel>
<tk:DataGrid MaxHeight="200" AutoGenerateColumns="False"
ItemsSource="{Binding}"
IsReadOnly="True">
<tk:DataGrid.Columns>
<tk:DataGridTextColumn Header="Key"
Binding="{Binding Key, Mode=OneWay}"/>
<tk:DataGridTextColumn Header="Value"
Binding="{Binding Value, Mode=OneWay}"/>
</tk:DataGrid.Columns>
</tk:DataGrid>
<charting:Chart MaxHeight="300"
Title="Title"
LegendTitle="Legend"
Name="Chart1">
<charting:AreaSeries DependentValuePath="Value"
IndependentValuePath="Key"
Background="Red" >
<charting:DataPointSeries.ItemsSource>
<Binding BindsDirectlyToSource="True"/>
</charting:DataPointSeries.ItemsSource>
</charting:AreaSeries>
</charting:Chart>
<Button Content="Change DataGrid and Chart Data" Click="Button_Click"/>
</StackPanel>
In code behind we reset the data context of the window ....
private List<KeyValuePair<int, int>> list1;
public Window1()
{
InitializeComponent();
list1 = new List<KeyValuePair<int, int>>();
var random = new Random();
for(int i = 0; i < 1000; i++)
{
list1.Add(new KeyValuePair<int, int>(i, random.Next()));
}
this.DataContext = list1;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
list1 = new List<KeyValuePair<int, int>>();
var random = new Random();
for (int i = 0; i < 1000; i++)
{
list1.Add(new KeyValuePair<int, int>(i, random.Next()));
}
this.DataContext = list1;
}
Everytime you click the button the chart refreshes without error.
Let me know if this helps.
I've received the same exception in different situation. I work with code which takes collection of existing UIElements and create new UIElement and set first one as Content of second one. Aditionally, it takes property value from existing UIElement and set it as value of different property of new UIElement.
foreach(UIElement insideElement in uiElementCollection)
{
var outsideElement = new TabItem
{
Content = insideElement
,Header = insideElement.Title
}
}
But in this case Title of inside property can be a Binding, but code above copies only value and when insideElement.Title is bounded to some source, outsideElement.Header doesn't reflect change.
So I changed code to bind HeaderProperty to TitleProperty of insideElement:
foreach(UIElement insideElement in uiElementCollection)
{
var outsideElement = new TabItem
{
Content = insideElement
}
outsideElement.SetBinding(HeaderedContentControl.HeaderProperty,
new Binding
{
Source = insideElement,
Path = new PropertyPath(MyUIElement.TitleProperty)
});
}
But when I executed code above, I received
System.InvalidOperationException: Cannot modify the logical children for this node at this time because a tree walk is in progress.
I found that I can't bind one dependency property to another one, which is stored inside Content property.
I tried to get binding expression of innerUIElement and set it as new binding to HeaderProperty of outsideUIElement.
foreach(UIElement insideElement in uiElementCollection)
{
var outsideElement = new TabItem
{
Content = insideElement
}
BindingExpression titleBindingExpression = pageControl.GetBindingExpression(MyUIElement.TitleProperty);
if (titleBindingExpression != null)
{
tabItem.SetBinding(HeaderedContentControl.HeaderProperty, new Binding { Source = titleBindingExpression.DataItem, Path = titleBindingExpression.ParentBinding.Path });
}
else
{
tabItem.Header = innerUIElement.Title;
}
}
Now, outer UI Element is binded to same source and WPF presenter doesn't throw Exception. My problem is solved.
I know this has been a while, but in case anyone else comes across it I found another way around it. Put the chart into a StackPanel, created with Visibility of "Collapsed" ("Hidden" DOES NOT WORK). Then set visibility to "Visible" after setting DataContext the first time (I'm doing it every time, but after the first it's redundant).
My experience agrees with reports I've seen that the problem is a bug that occurs when setting a non-empty DataContext after having had an empty one; but apparently it doesn't do the "tree walk" if the chart is collapsed.

Update text in adorner on button click

I have created my custom adorner to cover my main window with a gray canvas alongwith a textblock at center to show some status text while i was working on other window.
What i am currently doing is fetching the required adornerElement(ie Canvas with a textblock) from my resources and passing it to an adorner in my view constructor like this -
ResourceDictionary reportResourceDictionary = App.LoadComponent(new Uri("Resources/ReportResources.xaml", UriKind.Relative)) as ResourceDictionary;
UIElement adornerElement = reportResourceDictionary["RefreshingReportAdorner"] as UIElement;
mainWindowBlockMessageAdorner = new MainWindowBlockMessageAdorner(mainPanel, adornerElement);
But i want to update that text in textblock in some scenarios say if i click on some button in other window but how to update the text dynamically??
Adorner element from Resource file-
<Grid x:Key="RefreshingReportAdorner">
<Rectangle Fill="Gray"
StrokeThickness="1"
Stroke="Gray"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<Border BorderBrush="Black"
BorderThickness="2"
Background="White"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<TextBlock i18n:LanguageManager.VisualId="6"
Text="Some Text(Update dynamically)"
Padding="15,10,15,10"/>
</Border>
</Grid>
Let me know if additional code or approach required..
Have you tried to create some model and push it to RefreshingReportAdorner element's DataContext?
Code:
var reportResourceDictionary = App.LoadComponent(new Uri("Resources/ReportResources.xaml", UriKind.Relative)) as ResourceDictionary;
var adornerElement = reportResourceDictionary["RefreshingReportAdorner"] as FrameworkElement;
var model = new Model();
model.MyText = "Initial text";
adornerElement.DataContext = model;
mainWindowBlockMessageAdorner = new MainWindowBlockMessageAdorner(mainPanel, adornerElement);
...
model.MyText = "Text after click";
XAML:
<TextBlock i18n:LanguageManager.VisualId="6"
Text="{Binding MyText}"
Padding="15,10,15,10"/>
Model:
public class Item : INotifyPropertyChanged
{
private string _myText;
public string MyText
{
get
{
return this._myText;
}
set
{
this._myText= value;
this.OnPropertyChanged("MyText");
}
}
}

WPF ComboBox clear

I have Two radio buttons. If i check first radio button The below data will populate in the combobox. After that i will check another radio button, i want to clear the combo box values.
<RadioButton Height="29"
HorizontalAlignment="Left"
Margin="143,193,0,0" Name="rdoEmployee" VerticalAlignment="Top" Width="61"
FontSize="20" Checked="rdoEmployee_Checked" GroupName="rdoEmployee/>
<RadioButton FontSize="20" Height="20" Margin="228,193,0,0" Name="rdoPA"
VerticalAlignment="Top" HorizontalAlignment="Left" Width="49"
Checked="rdoPA_Checked" GroupName="rdoEmployee />
<ComboBox HorizontalAlignment="Left" Margin="142,235,0,240"
Name="cmbEmpType" Width="200" FontSize="16" />
EmployeeTypes _ET = new EmployeeTypes();
DataRowCollection drc = _ET.EmpTypeTable.Rows;
foreach (DataRow r in drc)
{
ComboBoxItem item = new ComboBoxItem();
item.Tag = r["EmpTypeID"];
item.Content = r["EmpTypeName"];
cmbEmpType.Items.Add(item);
if (cmbEmpType.Items.Count > 0)
{
cmbEmpType.SelectedIndex = 0;
}
}
Are you asking for
cmbEmpType.Items.Clear();
This should empty your combo.
Is it bound? If so, set the bound property to null. If not, set SelectedItem to null.

Resources