문제

나는 ItemsControl 개념적으로 관련이없는 출처에서 데이터를 가져와야합니다. 예를 들어, 다음과 같이 항목 클래스가 있다고 가정합니다.

public class Item
{
    public string ItemDescription { get; set; }
    public string ItemName { get; set; }
}

다음과 같이 툴팁을 사용하여 항목 통제 내에 항목을 표시 할 수 있습니다.

<ItemsControl x:Name="itemsControl" ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ItemName}">
                <TextBlock.ToolTip>
                    <ToolTip>
                        <TextBlock Text="{Binding ItemDescription}" />
                    </ToolTip>
                </TextBlock.ToolTip>
            </TextBlock>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

그러나 나는 DataContextItemsControl. 툴팁 내에서이를 수행 할 수있는 방법이 있습니까? 예,

<ItemsControl x:Name="itemsControl" ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ItemName}">
                <TextBlock.ToolTip>
                    <ToolTip>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <TextBlock Text="{Binding ItemDescription}" />
                            <TextBlock Grid.Row="1" Text="{Bind this to another property of the ItemsControl DataContext}" />
                        </Grid>
                    </ToolTip>
                </TextBlock.ToolTip>
            </TextBlock>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

내가 사용한 테스트 창의 코드는 다음과 같습니다.

public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        List<Item> itemList = new List<Item>() {
            new Item() { ItemName = "First Item", ItemDescription = "This is the first item." },
            new Item() { ItemName = "Second Item", ItemDescription = "This is the second item." } 
        };

        this.Items = itemList;
        this.GlobalText = "Something else for the tooltip.";
        this.DataContext = this;
    }

    public string GlobalText { get; private set; }

    public List<Item> Items { get; private set; }
}

그래서이 예에서 나는 GlobalText 속성 (실제로 이것은 또 다른 사용자 정의 객체 일 것입니다).

문제를 복잡하게하기 위해 실제로 DataTemplates를 사용하고 있으며 ItemsControl 내에 두 가지 다른 유형의 객체를 표시하지만 모든 도움은 크게 감사하겠습니다!

도움이 되었습니까?

해결책

한 시간의 머리카락을 당기고 난 후에 나는 당신이 데이터 emplate 내부에서 다른 데이터 콘텍스트를 참조 할 수 없다는 확신을 얻었습니다. 툴팁의 경우. 다른 바인딩의 경우 다른 포스터가 입증 된 것처럼 완벽하게 가능합니다. 그렇기 때문에 친척 소스 트릭을 사용할 수 없습니다. 당신이 할 수있는 것은 항목 클래스 및 참조에서 정적 속성을 구현하는 것입니다. 저것:

<Window x:Class="ToolTipSpike.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300"
    Name="Root"
    xmlns:ToolTipSpike="clr-namespace:ToolTipSpike">
    <Grid>
        <ItemsControl x:Name="itemsControl" ItemsSource="{Binding Items}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding ItemName}"> 
                        <TextBlock.ToolTip>
                            <ToolTip>
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition />
                                        <RowDefinition />
                                    </Grid.RowDefinitions>
                                    <TextBlock Text="{Binding ItemDescription}" />
                                    <TextBlock Grid.Row="1" 
                   Text="{Binding Source={x:Static ToolTipSpike:Item.GlobalText},
                   Path=.}"
                                    />
                                </Grid>
                            </ToolTip>
                        </TextBlock.ToolTip>
                    </TextBlock>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

using System.Collections.Generic;
using System.Windows;

namespace ToolTipSpike
{
    public partial class Window1 : Window
    {

        public List<Item> Items { get; private set; }
        public Window1()
        {
            InitializeComponent();
            var itemList = new List<Item>
                  {
                      new Item { ItemName = "First Item", ItemDescription = "This is the first item." },
                      new Item { ItemName = "Second Item", ItemDescription = "This is the second item." }
                  };
            this.Items = itemList;
            this.DataContext = this;
       }
    }

     public class Item
     {
         static Item()
         {
             GlobalText = "Additional Text";
         }
         public static string GlobalText { get; set; }
         public string ItemName{ get; set;}
         public string ItemDescription{ get; set;}
     }
}

다른 팁

두 번째 시도

좋아, 상대 소스 바인딩은 작동하지 않습니다 이 경우. 실제로 데이터 템플릿에서 작동하며 인터넷에서 이에 대한 많은 예를 찾을 수 있습니다. 그러나 여기 (당신은 옳았습니다, David, 당신의 의견에서) 툴팁은 visualtree에 올바르게 배치되지 않는 특별한 짐승입니다 (그것은 제어 자체가 아닌 속성입니다). 상대 바인딩을 사용하십시오.

좀 더 검색 한 후 나는 찾았다 이 기사, 이 효과를 세부 사항으로 설명하고 BindableToolTip의 구현을 제안합니다.

클래스에서 정적 속성을 사용하거나 (Dabblernl의 응답에서와 같이) 다른 옵션이 있기 때문에 과잉 일 수 있습니다. Item.

첫번째 시도 :)

상대 소스 바인딩 유형과 상담해야합니다 ( 이 치트 시트 예를 들어):

따라서 바인딩은 어떻게 든 이것과 유사하게 보일 것입니다.

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path= GlobalText}

거의 올바른 Yacoder와 Dabblernl;)

귀하의 사고 방식은 정확하며 Itemscontrol의 데이터 콘텍스트를 참조 할 수 있습니다.

경로에서 DataContext 속성이 누락되었습니다.

{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.GlobalText}

두 번째 시도;)

http://blogs.msdn.com/tom_mathews/archive/2006/11/06/binding-a-tooltip-in-xaml.aspx

다음은 같은 문제가있는 기사입니다. PlacementTarget 속성으로 부모 컨트롤의 데이터 콘텍스트를 참조 할 수 있습니다.

<ToolTip DataContext=”{Binding RelativeSource={RelativeSource Self},Path=PlacementTarget.Parent}”>

DataContext를 더 깊은 수준으로 배치하는 경우 항목 Datacontext 변경을 피하십시오.

두 번째 제안 (Neil과 Adam Smith)은 우리가 바인딩에 배치를 사용할 수 있다는 것입니다. 실제로 데이터 콘트 롤을 호스팅하는 페이지에서 이미 데이터 컨텍스트를 상속하고 있기 때문에 이것은 좋습니다.이를 통해 툴팁이 오리지널 컨트롤에 다시 액세스 할 수 있습니다. 그러나 Adam이 지적했듯이, 당신은 당신의 마크 업에서 부모/자식 구조를 알고 있어야합니다.

이것은 어쨌든보기보다보기 모델에서 이것을하는 것이 개념적으로 더 적합하다고 생각하는 경우입니다. 도구 팁 정보를보기 모델 항목의 속성으로보기에 노출하십시오. 이는보기가 (항목의 속성을 제시)에서 잘하는 것을 수행 할 수있게하고보기 모델은 (어떤 정보를 제시 해야하는지 결정)에서 잘하는 것을 수행합니다.

나는 매우 비슷한 문제가 있었고이 질문에 답하기 위해 도달했습니다. 결국 나는 내 경우에 효과가 있었고 다른 사람들에게 유용 할 수있는 다른 솔루션을 생각해 냈습니다.

내 솔루션에서 나는 부모 모델을 참조하는 어린이 항목에 속성을 추가하고 어린이가 생성 될 때 채워졌습니다. 툴팁의 XAML에서 각 요소의 상위 모델에서 속성을 참조하고 Datacontext를 부모 모델 속성으로 설정했습니다.

XAML에서 프록시 요소를 작성하고 참조하는 것 보다이 솔루션에 대해 더 편한 느낌이 들었습니다.

이 질문의 예제 코드를 사용하면 다음을 수행합니다. 참고 컴파일러 에서이 시나리오를 테스트하지는 않았지만 내 시나리오에 대한 코드 에서이 솔루션을 성공적으로 구현했습니다.

안건:

public class Item
{
    public List<Item> Parent { get; set; }
    public string ItemDescription { get; set; }
    public string ItemName { get; set; }
}

창문:

public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            List<Item> itemList = new List<Item>();
            itemList.Add(new Item() { Parent = this, ItemName = "First Item", ItemDescription = "This is the first item." });
            itemList.Add(new Item() { Parent = this, ItemName = "Second Item", ItemDescription = "This is the second item." });


            this.Items = itemList;
            this.GlobalText = "Something else for the tooltip.";
            this.DataContext = this;
        }

        public string GlobalText { get; private set; }

        public List<Item> Items { get; private set; }
    }

XAML :

<ItemsControl x:Name="itemsControl" ItemsSource="{Binding Items}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ItemName}">
                <TextBlock.ToolTip>
                    <ToolTip>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <TextBlock Text="{Binding ItemDescription}" />
                            <TextBlock Grid.Row="1" DataContext={Binding Parent} Text="{Bind this to aproperty of the parent data model}" />
                        </Grid>
                    </ToolTip>
                </TextBlock.ToolTip>
            </TextBlock>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top