SfChat with preview of attached image and changed styling

How can I achieve a result like in this image?
I did not find any way to attach an image preview like this.
Nor did I manage to change the location of the attachment button.

16 Replies 1 reply marked as answer

SS Sivaraman Sivagurunathan Syncfusion Team October 13, 2020 07:03 AM UTC

Hi Elhar, 

Thanks for using Syncfusion controls. 

We have checked your query. you can achieved your requirement in sample level. We have pared the sample based on your requirement. In that sample we have using SfPopupLayout to show the image preview. If you want to show the image preview in  Editor place you can load your custom footer by setting ShowMessageInputView as false in SfChat. We have attached the sample for your reference you can download the same from the below link. 


ImageMessage ImageMessage; 
ImageSource imageSource; 
SfPopupLayout pop; 
private void createMessage(Stream stream , EventArgs args) 
    byte[] imageBytes = ReadFully(stream); 
    imageSource = Xamarin.Forms.ImageSource.FromStream(() => new MemoryStream(imageBytes)); 
    pop = new SfPopupLayout(); 
    pop.PopupView.ShowHeader = false; 
    DataTemplate bodyTemplateView = new DataTemplate(() => 
    { 
        var imageView = new Image(); 
        imageView.BackgroundColor = Color.Black; 
        imageView.Source = imageSource; 
        imageView.Margin = new Thickness(0, 20, 0, 20); 
        return imageView; 
    }); 
    DataTemplate footerTemplateView = new DataTemplate(() => 
    { 
        StackLayout stack = new StackLayout() { Orientation = StackOrientation.Horizontal, HorizontalOptions = LayoutOptions.EndAndExpand }; 

        Button cancelButton = new Button(); 
        cancelButton.BackgroundColor = Color.Transparent; 
        cancelButton.Text = "Cancel"; 
        cancelButton.Clicked += CancelButton_Clicked; 

        Button oKButton = new Button(); 
        oKButton.Text = "Send"; 
        oKButton.BackgroundColor = Color.Transparent; 
        oKButton.Clicked += OKButton_Clicked; 
        stack.Children.Add(cancelButton); 
        stack.Children.Add(oKButton); 
        return stack; 
    }); 

    pop.PopupView.ContentTemplate = bodyTemplateView; 
    pop.PopupView.FooterTemplate = footerTemplateView; 
    pop.ShowRelativeToView(Chat.Editor.Parent.Parent as View, RelativePosition.AlignTop, absoluteY: -5); 
    this.ViewModel.attachmentPopup.Dismiss(); 

private void OKButton_Clicked(object sender, EventArgs e) 
    ImageMessage = new ImageMessage(); 
    ImageMessage.Aspect = Aspect.Fill; 

    ImageMessage.Source = imageSource; 
    ImageMessage.Author = this.ViewModel.CurrentUser; 
    this.ViewModel.Messages.Add(ImageMessage); 
    pop.IsOpen = false; 



Regards, 
Sivaraman S 



EK Elhar Kesser October 13, 2020 01:07 PM UTC

Sorry, but it seems like this sample doesn't work for me for some reason.
Whenever I tap the attachments button nothing happens.
When I replaced AttachmentButtonTapped code to this:
        private void AttachmentButtonTapped(object args)
        {
            attachmentPopup = new SfPopupLayout();
            attachmentPopup.PopupView.ShowHeader = false;
            attachmentPopup.PopupView.ShowFooter = false;
            // TestPage is a ContentPage with a single Label
            DataTemplate bodyTemplateView = new DataTemplate(() => new TestPage()); 
            attachmentPopup.ShowRelativeToView((args as SfChat).Editor.Parent.Parent as View, RelativePosition.AlignTop, absoluteY: -5);
        }

The whole screen becomes darker but nothing else happens:



Seems like SfPopupLayout isn't working properly for me.
I did not change NuGet versions of Syncfusion packages you set in this project.
Debug output also shows no errors.


SS Sivaraman Sivagurunathan Syncfusion Team October 14, 2020 06:45 AM UTC

Hi  Elhar, 

Thanks for your update. 

We have checked your query and attached sample. In that you have create the new SfPopupLayout and set ShowHeader and ShowFooter as false But does not set the SfPopupLayout.PopupView.ContentTemplate. If you set the ContentTemplate as bodyTemplateView it will be load. Also can you please check whether the you have initialization  the SfPopupLayoutRenderer in MainActivity. In our sample which provide in last update. Popup load with images. Please refer the following screenshots. If the issue still occurs from your side please revert us with modified sample with Syncfusion product version, Xamarin.Forms version and device details. It will help us to provide the better solution.  

 

 

Regards, 
Sivaraman S   


EK Elhar Kesser October 14, 2020 12:50 PM UTC

I see you don't understand.
It isn't working even in your original sample.
This your code — it doesn't work:

private void AttachmentButtonTapped(object args)
{
AttachmentPopupView popupTemplate = new AttachmentPopupView();
popupTemplate.ViewModel = this;
popupTemplate.Chat = args as SfChat;
attachmentPopup = new SfPopupLayout();
attachmentPopup.PopupView.ShowHeader = false;
attachmentPopup.PopupView.ShowFooter = false;
attachmentPopup.PopupView.AnimationMode = AnimationMode.Fade;
attachmentPopup.PopupView.PopupStyle.BorderThickness = 0;
attachmentPopup.PopupView.PopupStyle.CornerRadius = 45;
attachmentPopup.PopupView.WidthRequest = ((args as SfChat).Editor.Parent.Parent as View).Width;
attachmentPopup.PopupView.HeightRequest = 170;

DataTemplate bodyTemplateView = new DataTemplate(() =>
{
return popupTemplate;
});

attachmentPopup.PopupView.ContentTemplate = bodyTemplateView;
attachmentPopup.ShowRelativeToView((args as SfChat).Editor.Parent.Parent as View, RelativePosition.AlignTop, absoluteY: -5);
}



EK Elhar Kesser October 14, 2020 01:22 PM UTC

Seems like exactly ShowRelativeToView doesn't work.
Because if I change in your code ShowRelativeToView to Show everything shows even though positioning is wrong. 
I changed literally nothing else this time.
Any ideas why is it so?

private void AttachmentButtonTapped(object args)
{
AttachmentPopupView popupTemplate = new AttachmentPopupView();
popupTemplate.ViewModel = this;
popupTemplate.Chat = args as SfChat;
attachmentPopup = new SfPopupLayout();
attachmentPopup.PopupView.ShowHeader = false;
attachmentPopup.PopupView.ShowFooter = false;
attachmentPopup.PopupView.AnimationMode = AnimationMode.Fade;
attachmentPopup.PopupView.PopupStyle.BorderThickness = 0;
attachmentPopup.PopupView.PopupStyle.CornerRadius = 45;
attachmentPopup.PopupView.WidthRequest = ((args as SfChat).Editor.Parent.Parent as View).Width;
attachmentPopup.PopupView.HeightRequest = 170;

DataTemplate bodyTemplateView = new DataTemplate(() =>
{
return popupTemplate;
});

attachmentPopup.PopupView.ContentTemplate = bodyTemplateView;
//attachmentPopup.ShowRelativeToView((args as SfChat).Editor.Parent.Parent as View, RelativePosition.AlignTop, absoluteY: -5);
attachmentPopup.Show();
}


SS Sivaraman Sivagurunathan Syncfusion Team October 15, 2020 08:02 AM UTC

Hi Elhar, 

Thanks for your update. 

We have checked your query. In that, we have call ShowRelativeToView method to show the popup above the editor view. If you call show method popup shown at the center of the screen. ShowRelativeToView method is working from for us. We have checked the issue Oneplus 6T device. Can please let us known which device you have use to check the issue? Can you please please provide the video reference and device details to ensure the issue from our side? 

Regards, 
Sivaraman S 



EK Elhar Kesser October 15, 2020 09:44 AM UTC

Here it is, I use Genymotion emulator with Google Pixel 2 image (Android 8.0):



Shortly afterwards I also tried other Android versions like 7.1.2 and 9.0 and 2 more emulators. 
None of them worked with ShowRelativeToView.


KK Karthikraja Kalaimani Syncfusion Team October 16, 2020 01:55 PM UTC

Hi Elhar,

Thanks for the update.

We have checked the reported issue in source level. We found that the when multiply the Nan value with device density value, it returns negative value from framework in the Emulators. So, it tends to position the  PopupView at wrong place. To overcome this issue pass the Absolute X value as 0 on ShowRelativeView method. For more details please refer to the below code snippet.

Code snippet :

 
 
            AttachmentPopupView popupTemplate = new AttachmentPopupView(); 
            popupTemplate.ViewModel = this; 
            popupTemplate.Chat = args as SfChat; 
            attachmentPopup = new SfPopupLayout(); 
            attachmentPopup.PopupView.ShowHeader = false; 
            attachmentPopup.PopupView.ShowFooter = false; 
            attachmentPopup.PopupView.AnimationMode = AnimationMode.Fade; 
            attachmentPopup.PopupView.PopupStyle.BorderThickness = 0; 
            attachmentPopup.PopupView.PopupStyle.CornerRadius = 45; 
            attachmentPopup.PopupView.WidthRequest = ((args as SfChat).Editor.Parent.Parent as View).Width; 
            attachmentPopup.PopupView.HeightRequest = 170; 
 
            DataTemplate bodyTemplateView = new DataTemplate(() => 
            { 
                return popupTemplate; 
            }); 
 
            attachmentPopup.PopupView.ContentTemplate = bodyTemplateView; 
            attachmentPopup.ShowRelativeToView((args as SfChat).Editor.Parent.Parent as View, RelativePosition.AlignTop, 0, -5); 

Regards,
Karthik Raja 


Marked as answer

EK Elhar Kesser October 17, 2020 12:21 AM UTC

Yes, this is it! SF support team does a great job.
Especially comparing to something like Nvidia where in 95% cases you won't get any help at all.


SS Sivaraman Sivagurunathan Syncfusion Team October 19, 2020 05:34 AM UTC

Hi Elhar,  
  
We are happy to hear from you. Please get in touch with us if you would require any further assistance.       
      
Regards,       
Sivaraman S       



EK Elhar Kesser October 19, 2020 11:32 AM UTC

Oh almost forgot, there are couple more things: 

1. How can I change SfChatEditor corner radius? I want it rectangular.

2. How can I remove a suggestions bar (or what is this bar between SfChatEditor and chat itself)?
I marked this area with a red dashed line. I scrolled image message a bit so you can see where it takes space. 
I don't intend to use suggestions or typing indicator, so it really just takes useful space for me.





SS Sivaraman Sivagurunathan Syncfusion Team October 20, 2020 06:37 AM UTC

Hi Elhar, 

Thanks for your update. 

We have checked your query. you can achieve your requirement by set the CornerRadius for border and set FooterSize as 0 for ChatListView. Please refer the following code snippet. We have prepared the sample beased on your requirement and attached for your reference. You can download the same from the below link. 


ChatView.LoadMoreCommand = viewModel.LoadMoreCommand; 
var listview = (SfListView)ChatView.GetType().GetRuntimeProperties().FirstOrDefault(x => x.Name.Equals("ChatListView")).GetValue(ChatView); 
listview.FooterSize = 0; 
FooterView footerView = (FooterView)(this.ChatView.Content as Grid).Children[1]; 
ContentView contentView = (ContentView)(footerView as Grid).Children[1]; 
var border = (contentView.Content as SfBorder); 
border.CornerRadius = new Thickness(0); 



Regards, 
Sivaraman S 



EK Elhar Kesser October 20, 2020 08:25 AM UTC

Oh, thanks a lot.
But how can I combine it with SyncfusionThemeDictionary?
Like this one:

<ContentPage.Resources>
<syncTheme:SyncfusionThemeDictionary>
<syncTheme:SyncfusionThemeDictionary.MergedDictionaries>
<ResourceDictionary>
<x:String x:Key="SfChatTheme">CustomTheme</x:String>
<Color x:Key="SfChatMessageInputViewBackgroundColor">White</Color>
<Color x:Key="SfChatEditorBorderColor">Blue</Color>
</ResourceDictionary>
</syncTheme:SyncfusionThemeDictionary.MergedDictionaries>
</syncTheme:SyncfusionThemeDictionary>
</ContentPage.Resources>

If I try to use it — it resets corner radius to default.


SS Sivaraman Sivagurunathan Syncfusion Team October 21, 2020 03:56 AM UTC

Hi Elhar, 

Thanks for your update. 

We have checked your query. We cannot able to achieve this using SyncfusionThemeDictionary. In our pervious update we provide a solution as workaround for your requirement. We cannot directly access that properties.  

Regards, 
Sivaraman S 



EK Elhar Kesser October 21, 2020 12:44 PM UTC

OK, what about the other way around?
I understand how to change BorderColor:

var listview = (SfListView)sfChat.GetType().GetRuntimeProperties().FirstOrDefault(x => x.Name.Equals("ChatListView")).GetValue(sfChat);
listview.FooterSize = 0;
FooterView footerView = (FooterView)(this.sfChat.Content as Grid).Children[1];
ContentView contentView = (ContentView)(footerView as Grid).Children[1];
var border = (contentView.Content as SfBorder);
border.CornerRadius = new Thickness(0);
border.BorderColor = Color.Blue;

But what about SfChatMessageInputViewBackgroundColor? How to access it from code bihind like BorderColor?

Also I've got another question: how to make that on SfPopupLayout.Opening event (IsOpen = true)  would be called ShowRelativeToView() instead of Show()?
I attached a sample project.

Attachment: Sample_62863bd7.zip


KK Karthikraja Kalaimani Syncfusion Team October 22, 2020 12:32 PM UTC

Hi Elhar,

Please refer to the below code snippet to access the SfChatInputViewBackgroundColor from code behind.

Code snippet :

 
            var listview = (SfListView)sfChat.GetType().GetRuntimeProperties().FirstOrDefault(x => x.Name.Equals("ChatListView")).GetValue(sfChat); 
            listview.FooterSize = 0; 
            FooterView footerView = (FooterView)(this.sfChat.Content as Grid).Children[1]; 
            ContentView contentView = (ContentView)(footerView as Grid).Children[1]; 
            var border = (contentView.Content as SfBorder); 
            ((border.Content as Grid).Children[0] as Editor).BackgroundColor = Color.Red; 
            border.CornerRadius = new Thickness(0); 
            border.BorderColor = Color.Blue; 

Regarding the query “how to open the popupview as ShowRelativeToView by using IsOpen property”, please refer the below code snippet to achieve your requirement.

Code snippet :

 
<sfPopup:SfPopupLayout x:Name="Popup1" IsOpen="{Binding ShowPopupImage}" StaysOpen="{Binding ShowPopupImage}"> 
                           <sfPopup:SfPopupLayout.PopupView> 
                                 <sfPopup:PopupView AppearanceMode="TwoButton" ShowHeader="False"> 
 
                                        <sfPopup:PopupView.ContentTemplate> 
                                               <DataTemplate> 
                                                     <Image Source="{Binding ImageSourceBinding}" BackgroundColor="LightGray"/> 
                                               </DataTemplate> 
                                        </sfPopup:PopupView.ContentTemplate> 
 
                                        <sfPopup:PopupView.FooterTemplate> 
                                               <DataTemplate> 
                                                     <StackLayout Orientation="Horizontal" HorizontalOptions="EndAndExpand"> 
                                                            <buttons:SfButton Text="Remove" Command="{Binding RemoveImageSourceCommand}"/> 
                                                            <buttons:SfButton Text="Hide" Command="{Binding HideImageCommand}"/> 
                                                     </StackLayout> 
                                               </DataTemplate> 
                                        </sfPopup:PopupView.FooterTemplate> 
 
                                 </sfPopup:PopupView> 
                           </sfPopup:SfPopupLayout.PopupView> 
                    </sfPopup:SfPopupLayout>


//Code behind
            Popup1.RelativeView = (sfChat.Editor.Parent.Parent as View); 
            Popup1.AbsoluteX = 0; 
            Popup1.AbsoluteY = -5; 
            Popup1.RelativePosition = RelativePosition.AlignTop; 


Loader.
Up arrow icon