0

I have a DataTemplate:

    <DataTemplate x:Key="BMSelectedItemTemplate">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="*" Visibility=???/>
            <TextBlock Text="{Binding Name}"/>
        </StackPanel>
    </DataTemplate>

I have a DataTemplateSelector using the above template:

    <BookmarkItemDataTemplateSelector x:Key="BookmarkItemDataTemplateSelector" SelectedItemTemplate="{StaticResource BMSelectedItemTemplate}" 
                                                                                      DropdownItemsTemplate="{StaticResource BMDropdownItemTemplate}" />

I use the above data template selector in a comboBox:

        <StackPanel x:Name="splBookmark" Visibility="{Binding ShowBookmark, Converter={StaticResource BooleanToVisibilityConverter}}">
            <ComboBox x:Name="cbBookmark" ItemTemplateSelector="{StaticResource BookmarkItemDataTemplateSelector}"/>
        </StackPanel>

My view model has properties ShowBookmark and ShowAsterisk. I want to bind visibility of the "*" in BMSelectedItemTemplate to my view model's property ShowAsterisk. How could I do that? I tried:

Visibility="{Binding ShowAsterisk, Converter={StaticResource BooleanToVisibilityConverter}}"

But it didn't work, it said data template cannot find property ShowAsterisk, I think this makes sense, because the data template is binding to a list of MBookmark objects, and in my MBookmark class, there is no property of ShowAsterisk. ShowAsterisk is a property of the view model which is binding to splBookmark stack panel.

My question is how to bind ancestor element's view model property to my data template element's visibility?

I cannot use relative path ancestor type to find my comboBox or stack panel, it seems I can only use self or TemplateParent in my relative source. I use silverlight.

Thank you!

Eli Arbel
  • 22,391
  • 3
  • 45
  • 71
spspli
  • 3,128
  • 11
  • 48
  • 75
  • Please see the marked duplicate for an example of one of several Stack Overflow questions that address how to bind to a view model of a parent of the current element. – Peter Duniho Aug 02 '16 at 16:51
  • Hi I take a look at the duplicated problem, but it seems I cannot use relative source in my binding, it cannot find the AncestorType property in RelativeSource. Do I have any other way to access splBookmark? – spspli Aug 02 '16 at 17:00
  • Sounds like you haven't typed the binding correctly. But without a good [mcve] that reliably reproduces your problem, it's not possible say for sure what the issue is. I can assure you, `RelativeSource` does work, as long as you use it correctly. – Peter Duniho Aug 02 '16 at 17:03
  • Thank you Peter, I am confused too, because when I use AncestorType it complains "The member AncestorType is not recognized or is not accessible". I am still struggling to figure out why this happens. – spspli Aug 02 '16 at 17:05
  • Hi Peter, I edited my post. I think this may relates to it's a UWP app, I see this:https://social.msdn.microsoft.com/Forums/vstudio/en-US/e424c478-fc04-4755-8837-b53006e162e6/the-property-ancestortype-was-not-found-in-type-relativesource-?forum=wpf – spspli Aug 02 '16 at 17:31
  • If I cannot use relativeSource, how can I use Source to find my splBookmark? Just Source=splBookmark? – spspli Aug 02 '16 at 17:32
  • Yes, it's important to provide all relevant information, including stating clearly what XAML-based API you're using. That said, your question is still a duplicate. See http://stackoverflow.com/questions/32861612/how-to-do-relativesource-mode-find-ancestor-or-equivalent-in-uwp – Peter Duniho Aug 02 '16 at 17:43

1 Answers1

1

In WPF, you can use RelativeSource to climb up the visual tree.

Assuming your items container is a ListBox:

Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, 
                     Path=DataContext.ShowAsterisk,
                     Converter={StaticResource BooleanToVisibilityConverter}}"

In a UWP app, where RelativeSource is not available, you can use ElementName instead.

First, name the items control:

<ComboBox Name="MyComboBox" />

Then, use it in the binding:

Visibility="{Binding ElementName=MyComboBox, 
                     Path=DataContext.ShowAsterisk,
                     Converter={StaticResource BooleanToVisibilityConverter}}"
Eli Arbel
  • 22,391
  • 3
  • 45
  • 71
  • My items container is a comboBox and the comboBox is on a stack panel. I cannot use the above code to find the ComboBox because it complains AncestorType is not a property of RelativeSource. Do you know any reason may cause this? – spspli Aug 02 '16 at 17:03
  • This is a UWP app. – spspli Aug 02 '16 at 17:27
  • Thank you Eli to point this out! – spspli Aug 02 '16 at 17:36
  • Hi Eli, all the stack panel, comboBox are in a user control, and my user control's name is ucMyControl, ucMyControl's contructor has this.DataContext = myViewModel; and ShowAsterisk is a property on myViewModel. I tried your code with: Visibility="{Binding ElementName=ucMyControl, Path=DataContext.ShowAsterisk, Converter={StaticResource BooleanToVisibilityConverter}}, it seems it still doesn't work. – spspli Aug 02 '16 at 18:09
  • I also tried to use Visibility="{Binding ElementName=cbBookmark, Path=DataContext.ShowAsterisk, Converter={StaticResource BooleanToVisibilityConverter}}, and it doesn't work neither. – spspli Aug 02 '16 at 18:12