How to set different HorizontalAlignment to ListBoxItems

前端 未结 5 1096
情歌与酒
情歌与酒 2021-01-21 12:12

I posted a question yesterday but I think I failed to explain it correctly.

Let me try again.

So this is my goal:

5条回答
  •  鱼传尺愫
    2021-01-21 12:24

    Note: I do not have Phone SDK so had to make do with normal WPF app. I have not used triggers as you mentioned they do not work.

    So I knocked up a simple app that looks like this

    enter image description here

    Here's the code:

    App.xaml.cs

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
    
            var mainvm = new MainWindowViewModel();
            var window = new MainWindow
            {
                DataContext = mainvm
            };
            window.Show();
    
            mainvm.Messages.Add(new OutgoingMessage{ MessageContent = "Help me please!"});
    
            mainvm.Messages.Add(new IncomingMessage { MessageContent = "What do you want" });
    
            mainvm.Messages.Add(new OutgoingMessage { MessageContent = "I want a ListBox" });
    
            mainvm.Messages.Add(new IncomingMessage { MessageContent = "Then?" });
    
            mainvm.Messages.Add(new OutgoingMessage { MessageContent = "But the Grid won't fill" });
        }
    }
    

    MainWindow.xaml

    
    
        
            
                
                
            
        
    
        
            
                
                
            
        
    
    
        
    
    

    ViewModelBase.cs

    public class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged(string propertyName)
        {
            this.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }
    
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, e);
            }
        }
    }
    

    MainWindowViewModel:

    public class MainWindowViewModel : ViewModelBase
    {
        public MainWindowViewModel()
        {
            Messages = new ObservableCollection();
        }
        public ObservableCollection Messages { get; protected set; }
    }
    

    Message.cs:

    public abstract class Message : ViewModelBase
    {
        private string _messageContent;
    
        public string MessageContent 
        {
            get
            {
                return this._messageContent;
            }
            set
            {
                this._messageContent = value;
                this.OnPropertyChanged("MessageContent");
            }
        }   
    }
    

    OutgoingMessage.cs

    public class OutgoingMessage : Message
    {
    }
    

    IncomingMessage.cs

    public class IncomingMessage : Message
    {
    }
    

    How this works I override the application startup so I can create viewmodels to populate my UI. You can see in the App.xaml.cs code I create the Window and show it, and then add the messages. I was going to use a timer but got lazy.

    If you look at the MainWindow.xaml, you will notice that I have 2 DataTemplates defined. One of them targets my IncomingMessageViewModel and the other targets the OutogingMessageViewModel. The local prefix is an alias for my application namespace. I have an ItemsControl that can contain the base type Message class, just so that I can have both Incoming and Outgoing messages in the same collection. This is bound to the Messages property on my MainWindowViewModel class. It is important to have incoming and outgoing messages as 2 separate classes as this is the magic that makes this work.

    An alternative technique would be to use a property with a style selector bound to the property as one of the other answers suggest, but this would mean that I would have to deal with UI specific logic in my ViewModel (which I don't like to do).

    To change the appearance of either Message type, just change the xaml code in the respective DataTemplate.

    Hope this helps.

提交回复
热议问题