0

I am building a UI design for chat app and I encountered a problem when trying to update messages of a selected contact. Uppon selecting a exsisting contact, choosing an edit option and then editing its properties like username and image, the only changes that are made are the username and the image of an contact. I still want to change the Username and image of a MessageModel which is included in my ContactModel as observable collection.

Here is my ContactModel class code:

namespace UV_MessagingApp.MVVM.Model
{
    public class ContactModel
    {
        public string Username { get; set; }
        public ImageSource ImageSource { get; set; }
        public ObservableCollection<MessageModel> Messages { get; set; }
        public string LastMessage => Messages.Last().Message;
    }
}

Here is my MessageModel class code:

namespace UV_MessagingApp.MVVM.Model
{
    public class MessageModel
    {
        public string Username { get; set; }
        public string UsernameColor { get; set; }
        public ImageSource ImageSource { get; set; }
        public string Message { get; set; }
        public DateTime Time { get; set; }
        public bool? FirstMessage { get; set; }

    }
}

Here is the binding from "EditContact.xaml". I bind the Username property from ContactModel and I want to achieve that the changes will also be applied to MessageModel properties.

<TextBox Grid.Column="1" Grid.Row="0" Name="contactUsername" Background="Transparent"
                             Foreground="White" BorderBrush="#292B2F" Margin="2" Padding="2"
                             Text="{Binding SelectedContact.Username, Mode=TwoWay}"/>

And finally this is the ListView from MainWindow.xaml which is a list where messages are displayed. You can see that I have a "chatItem" where the properties of a MessageModel are binded:

<ListView ItemsSource="{Binding SelectedContact.Messages}"
                      Background="Transparent"
                      BorderThickness="0"
                      ItemContainerStyle="{StaticResource ChatItem}"
                      Margin="8,0,0,0"
                      Grid.Row="1">
            </ListView>

This is a ChatItem:

<StackPanel Orientation="Horizontal">
   <Ellipse Width="30" Height="30"
            Margin="10,0,0,-5">
        <Ellipse.Fill>
            <ImageBrush ImageSource="{Binding ImageSource}"
                                        RenderOptions.BitmapScalingMode="Fant">
            </ImageBrush>
        </Ellipse.Fill>
    </Ellipse>

    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="{Binding Username}"
                Foreground="{Binding UsernameColor}"
                FontWeight="SemiBold"
                VerticalAlignment="Center"
                Margin="0,0,-5,0">
            </Label>

            <Label Content="{Binding Time}"
                Foreground="#44474D"
                FontWeight="SemiBold"
                VerticalAlignment="Center">
            </Label>
        </StackPanel>

        <Label Content="{Binding Message}"
Foreground="White"
            FontWeight="SemiBold"
            VerticalAlignment="Center">
        </Label>
    </StackPanel>
</StackPanel>  

Here is the MainVievModel class with already imlemented INotifyPropertyChanged() function. Maybe should I use it somewhere else too?

public class MainViewModel : ObservableObject
    {
        //public ObservableCollection<MessageModel> Messages { get; set; }
        public ObservableCollection<ContactModel> Contacts { get; set; }

        /* Commands */
        public RelayCommand SendCommand { get; set; }

        private ContactModel _selectedContact;
        public  ContactModel SelectedContact
        {
            get{ return _selectedContact; }
            set
            {
                _selectedContact = value; 
                OnPropertyChanged();
            }
        }

        private string _message;
        
        public string Message
        {
            get { return _message; }
            set
            {
                _message = value;
                OnPropertyChanged();
            }
        }
        public MainViewModel()
        {
            //Messages = new ObservableCollection<MessageModel>();
            Contacts = new ObservableCollection<ContactModel>();

            // Pošiljanje sporočil
            //SendCommand = new RelayCommand(o =>
            //{
            //    Messages.Add(new MessageModel
            //
        }
    }

In the EditContact.xaml window I tried passing in the SelectedContact.Messages.Username binding but it doesn't work. So I would appreciate your help.

povodnikt
  • 27
  • 7
  • `Text="{Binding SelectedContact.Username}"` usually requires that the Username setter fires a change notification. – Clemens Nov 06 '22 at 14:38
  • @Clemens yeah, but that works, the problem is that it does not change the data in SelectedContact.Messages... – povodnikt Nov 06 '22 at 14:49
  • Your model objects will need to also implement `INotifyPropertyChanged` if you are binding to them.. The ObservableCollection only handles notifying on the collection changing not the properties of the individual objects. – Felix Castor Nov 06 '22 at 17:02
  • Another thing, you may want to use `UpdateSourceTrigger=PropertyChanged` in the TextBox binding. The default behavior is update when the element loses focus. – Felix Castor Nov 06 '22 at 17:07

0 Answers0