Domanda

How do I retrieve text from a textblock inside a listbox and display the text in a textbox?

What I want to do

First I want to be able to copy the text from the textblock inside the listbox

enter image description here

Then I want to display the text in the textbox

enter image description here

I tried using a visual tree helper but apparently it cannot find the 'FindName' method. Is there a better way to achieve this?

XAML Code

 <ListBox Name="ChatDialogBox" Height="550" ItemsSource="{Binding Path=Instance.Messages,Source={StaticResource Binder}}" > 
            <ListBox.ItemTemplate>  
                <DataTemplate>                   
                            <Grid>                       
                                <TextBlock Name="ChatMessage" Text="{Binding Text}" TextWrapping="Wrap" Width="430">         
                     <toolkit:ContextMenuService.ContextMenu>
                        <toolkit:ContextMenu Name="ContextMenu" >
                              <toolkit:MenuItem Name="Copy"  Header="Copy" Click="Copy_Click" />
                        </toolkit:ContextMenu>
                    </toolkit:ContextMenuService.ContextMenu>          
                                </TextBlock>                             
                            </Grid>                 
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Code Behind

 private void Copy_Click(object sender, RoutedEventArgs e)
    {

        ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(ChatDialogBox);
        DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
        TextBlock target = (TextBlock)myDataTemplate.FindName("ChatMessage", myContentPresenter);

    }


    private childItem FindVisualChild<childItem>(DependencyObject obj) where childItem : DependencyObject
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(obj, i);
            if (child != null && child is childItem)
                return (childItem)child;
            else
            {
                childItem childOfChild = FindVisualChild<childItem>(child);
                if (childOfChild != null)
                    return childOfChild;
            }
        }
        return null;
    }

Binder Class

 public class Binder : INotifyPropertyChanged
{
    static Binder instance = null;
    static readonly object padlock = new object();

    public Binder()
    {
        Messages = new ObservableCollection<Message>();
    }

    public static Binder Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance == null)
                {
                    instance = new Binder();
                }
                return instance;
            }
        }
    }

    private ObservableCollection<Message> messages;
    public ObservableCollection<Message> Messages
    {
        get
        {
            return messages;
        }
        set
        {
            if (messages != value)
            {
                messages = value;
                NotifyPropertyChanged("Messages");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => { PropertyChanged(this, new PropertyChangedEventArgs(info)); });
        }
    }
}

Message Class

 public class Message 
{
    public string Text { get; set; }

}
È stato utile?

Soluzione

There's an indirect but easier way to retrieve the content of the textblock.

In the click event, you can retrieve the object your model by using the DataContext property:

private void Copy_Click(object sender, RoutedEventArgs e)
{
    var model = (Message)((FrameworkElement)sender).DataContext;

    // Display model.Text in your TextBlock
}

Just replace Message by the type of the objects you've assigned to the ItemsSource of your listbox.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top