简体   繁体   English

C#WPF如何在后面的代码中获取绑定值

[英]C# WPF How to get binding value in code behind

I have a custom control ChatTextControl with 2 textbox and a button . 我有一个带有2个textbox和一个button的自定义控件ChatTextControl The xaml is like this : 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>

The pseudo and message come from the following class : 伪和消息来自以下类:

public class ChatListItemViewModel : BaseViewModel
{
    public string Pseudo { get; set; }

    public string Message { get; set; }

    public int Id { get; set; }
}

ChatTextControl is called in another custom control ChatListControl : 在另一个自定义控件ChatTextControl中调用ChatListControl

<Grid Background="White">
    <ScrollViewer VerticalScrollBarVisibility="Auto">
        <ItemsControl ItemsSource="{Binding Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:ChatTextControl />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </ScrollViewer>
</Grid>

In my main window I call ChatListControl like so : 在我的主窗口中,我这样调用ChatListControl

<local:ChatListControl x:Name="MyChat" Margin="389,10,10,38"/>

And set the DataContext in code behind : 并在代码后面设置DataContext:

ChatListModel chat = new ChatListModel();
MyChat.DataContext = chat;

ChatListModel : 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++;
    }
}

The goal is to use the Button_Click event in ChatTextControl to delete the element with the corresponding id in the list. 目标是使用ChatTextControl的Button_Click事件删除列表中具有相应ID的元素。 But i don't know how to get the id in the code behind whether it's in the ChatTextControl.cs or MainWindow.cs . 但是我不知道如何在ChatTextControl.csMainWindow.cs中的代码后面获取ID。

If someone know how to do it or have a better idea for the delete button please let me know. 如果有人知道该怎么做或对删除按钮有更好的主意,请告诉我。

You could for example set an IsDelete property in ChatListItemViewModel when the button is clicked, raise an event and handle this event in ChatListModel . 例如,您可以在单击按钮时在ChatListItemViewModel设置IsDelete属性,引发事件并在ChatListModel处理此事件。 You need to use an ObservableCollecton<T> instead of a List<T> for the item to get removed in the view: 您需要使用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: ChatTextControl.xaml:

<Button Grid.Column="1" Padding="8" VerticalAlignment="Top" Width="20" Height="20" 
        Background="{x:Null}" Command="{Binding DeleteCommand}" />

I could not verify the answer of mm8 because of the reason put in my comment, so here is the solution that I found. 由于评论中的原因,我无法验证mm8的答案,因此这是我找到的解决方案。

After putting break point in the Button_Click event, I noticed that I could obtain the Id of ChatListItemViewModel by casting the this.DataContext in ChatTextControl and send an event like this : 在Button_Click事件中放置断点后,我注意到可以通过在this.DataContextChatTextControl转换ChatTextControl并发送如下事件来获取ChatListItemViewModel的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);
    }

Doing so, I can get the Id and delete the item in the main window : 这样做,我可以获取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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM