问题
I'm plotting a histogram of a grayscale image using an array of 256 values. Im doing so by creating my own chart with 256 vertical rectangles (columns). My aim is that when I mouse over one rectangle I get its index value, its index from the array it lies in, like if I mouse over the 200th rectangle I get 200 in a small text box near cursor, like how ToolTip should perform. The problem is that I don't find the proper binding for ToolTip to get this working. I think the solution lies in the proper use of AlternationCount / AlternationIndex
Here is may XAML code, maybe someone can give me a fix for it:
<ItemsControl Grid.Row="1" ItemsSource="{Binding HistogramValues}" AlternationCount="{Binding Path=HistogramValues.Count}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Height="{Binding }" ToolTip="{Binding AlternationIndex, RelativeSource={RelativeSource AncestorType=ItemsControl}}" Width="2" VerticalAlignment="Bottom" Fill="Black"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
where in view model I have:
public float[] HistogramValues { get; set; }
I've found this useful post Numbered listbox but I still cant make it run for my case, I'm confused about that ItemTemplate and TemplatedParent which I dont know if I need or if I need the template how should I code this.
回答1:
If you are not ok with converters you can use this,
<ItemsControl Grid.Row="1" ItemsSource="{Binding Collection}" AlternationCount="{Binding Path=Collection.Count}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" ToolTip="{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContentPresenter}}">
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Since AlternationIndex is attached property, it should be covered with "()".
回答2:
If you dont specify source in a binding, it always binds to datacontext.
Do this
ToolTip="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource AncestorType=ContentPresenter}}"
回答3:
If showing the index is your only requirement you can achieve this like below,, MyConverter is a multiconverter ,and include that in resources
<ItemsControl Grid.Row="1" ItemsSource="{Binding Collection}" >
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Control.ToolTip">
<Setter.Value>
<MultiBinding Converter="{StaticResource MyConverter}">
<Binding Path="IsMouseOver" RelativeSource="{RelativeSource Self}"/>
<Binding />
<Binding Path="ItemsSource" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
public partial class MainWindow : Window
{
private ObservableCollection<string> collection;
public ObservableCollection<string> Collection
{
get { return collection; }
set { collection = value; }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
collection = new ObservableCollection<string>();
collection.Add("First");
collection.Add("Second");
collection.Add("Third");
collection.Add("Fourth");
}
}
public class MyConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if ((bool)values[0])
{
return (values[2] as ObservableCollection<string>).IndexOf(values[1].ToString());
}
else
return "";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
来源:https://stackoverflow.com/questions/28790131/tooltip-use-to-show-the-index-of-an-item-from-a-collection-c-sharp-wpf-mvvm