我有一个自定义控件ChatTextControl
,其中包含2个textbox
和一个button
。
xaml
就像这样:
<Grid Background="White">
<Grid.ColumnDefinitions>
<!-- Message -->
<ColumnDefinition Width="*"/>
<!-- delete message -->
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Message content -->
<StackPanel>
<TextBlock Text="{Binding Path= Pseudo}" FontWeight="SemiBold"/>
<TextBlock Text="{Binding Path= Message}" TextWrapping="Wrap"/>
</StackPanel>
<Button Grid.Column="1" Padding="8" VerticalAlignment="Top" Width="20" Height="20" Background="{x:Null}" Click="Button_Click"/>
</Grid>
伪和消息来自以下类:
public class ChatListItemViewModel : BaseViewModel
{
public string Pseudo { get; set; }
public string Message { get; set; }
public int Id { get; set; }
}
在另一个自定义控件ChatTextControl
中调用 ChatListControl
:
<Grid Background="White">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:ChatTextControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
在主窗口中,我这样叫ChatListControl
:
<local:ChatListControl x:Name="MyChat" Margin="389,10,10,38"/>
并在后面的代码中设置DataContext:
ChatListModel chat = new ChatListModel();
MyChat.DataContext = chat;
ChatListModel:
public class ChatListModel : ChatListViewModel
{
private static int idCount = 0;
public ChatListModel()
{
Items = new List<ChatListItemViewModel>();
}
public void AddMessage(string p, string m)
{
Items.Add(new ChatListItemViewModel
{
Pseudo = p,
Message = m,
Id = idCount
});
idCount++;
}
}
目标是使用ChatTextControl
中的Button_Click事件来删除列表中具有相应ID的元素。
但是我不知道如何在ChatTextControl.cs
或MainWindow.cs
中获得代码背后的ID。
如果有人知道该怎么做或对删除按钮有更好的主意,请告诉我。
答案 0 :(得分:0)
例如,您可以在单击按钮时在IsDelete
中设置ChatListItemViewModel
属性,在ChatListModel
中引发事件并处理该事件。您需要使用ObservableCollecton<T>
而不是List<T>
才能在视图中删除该项目:
public class ChatListModel : ChatListViewModel
{
private static int idCount = 0;
public ChatListModel()
{
Items = new ObservableCollection<ChatListItemViewModel>();
AddMessage("p", "m");
}
public void AddMessage(string p, string m)
{
ChatListItemViewModel newItem = new ChatListItemViewModel
{
Pseudo = p,
Message = m,
Id = idCount
};
newItem.PropertyChanged += NewItem_PropertyChanged;
Items.Add(newItem);
idCount++;
}
private void NewItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
ChatListItemViewModel removedItem = (ChatListItemViewModel)sender;
removedItem.PropertyChanged -= NewItem_PropertyChanged;
Items.Remove(removedItem);
idCount--;
}
public ObservableCollection<ChatListItemViewModel> Items { get; }
}
public class ChatListItemViewModel : BaseViewModel
{
public string Pseudo { get; set; }
public string Message { get; set; }
public int Id { get; set; }
private bool _isDeleted;
public bool IsDeleted
{
get { return _isDeleted; }
set { _isDeleted = value; OnPropertyChanged(nameof(IsDeleted)); }
}
public ChatListItemViewModel()
{
DeleteCommand = new RelayCommand(_ => true, _ => IsDeleted = true);
}
public ICommand DeleteCommand { get; }
}
ChatTextControl.xaml:
<Button Grid.Column="1" Padding="8" VerticalAlignment="Top" Width="20" Height="20"
Background="{x:Null}" Command="{Binding DeleteCommand}" />
答案 1 :(得分:0)
由于评论中的原因,我无法验证mm8的答案,所以这是我找到的解决方案。
在Break_Click事件中放置断点后,我注意到可以通过将ChatListItemViewModel
强制转换为this.DataContext
并发送如下事件来获取ChatTextControl
的ID:
public delegate void DeleteClick(int id);
public static event DeleteClick OnDeleteClick;
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
OnDeleteClick?.Invoke(((ChatListItemViewModel)this.DataContext).Id);
}
这样做,我可以获取ID并在主窗口中删除该项目:
public ChatListModel chat;
public MainWindow()
{
InitializeComponent();
chat = new ChatListModel();
chat.AddMessage(name, "Hello World!");
MyChat.DataContext = chat;
ChatTextControl.OnDeleteClick += ChatTextControl_OnDeleteClick;
}
private void ChatTextControl_OnDeleteClick(int id)
{
chat.DelMessage(id);
MyChat.DataContext = null;
MyChat.DataContext = chat;
}