Search code examples
wpfdata-bindingivalueconverter

how to pass value to converter which is a Property in the element which was bound


iv'e got a group of Shapes , i need to decide which stay visible and which hidden according to tow conditions (this will represent a dice visual )

(1) the value they receive via binding from their data context .

(2) the value of their place in the group which i saved for each shape in it's Tag property

i need the converter to get the Tag Property as a parameter for each Shape

my binding :( INCORRECT )

 <Style TargetType="{x:Type Ellipse}">
    <Setter Property="Visibility" Value="{Binding Path=., Converter={StaticResource MyDiceInputToVisualConverter}}"></Setter>
 </Style>

My Shapes :

 <Canvas DataContext="{Binding Path=DataContext.Dice1,RelativeSource={RelativeSource AncestorType=StackPanel}}">
      <Ellipse Tag="1" Canvas.Left="5" Canvas.Top="5"></Ellipse>
      <Ellipse Tag="2" Canvas.Left="5" Canvas.Top="20"></Ellipse>
      <Ellipse Tag="3" Canvas.Left="5" Canvas.Top="35"></Ellipse>
      <Ellipse Tag="4" Canvas.Left="20" Canvas.Top="20"></Ellipse>
      <Ellipse Tag="5" Canvas.Left="35" Canvas.Top="5"></Ellipse>
      <Ellipse Tag="6" Canvas.Left="35" Canvas.Top="20"></Ellipse>
      <Ellipse Tag="7" Canvas.Left="35" Canvas.Top="35"></Ellipse>
   </Canvas>

my converter should not be of interest all it does is return Visible or Hidden According to the dice value and the place of the Dot on the dice.

any ideas how i can send the converter the tag property or alternatively reference it with in the converter ?

thanks in advance .

EDIT :

i ended up explicitly setting the binding in the markup of each ellipse :

<Canvas DataContext="{Binding Path=DataContext.Dice1,RelativeSource={RelativeSource AncestorType=StackPanel}}">
     <Ellipse Tag="1" Canvas.Left="5" Canvas.Top="5" Visibility="{Binding Path=., Converter={StaticResource MyDiceInputToVisualConverter},ConverterParameter=1}"></Ellipse>
     <Ellipse Tag="2" Canvas.Left="5" Canvas.Top="20" Visibility="{Binding Path=., Converter={StaticResource MyDiceInputToVisualConverter},ConverterParameter=2}"></Ellipse>
     <Ellipse Tag="3" Canvas.Left="5" Canvas.Top="35" Visibility="{Binding Path=., Converter={StaticResource MyDiceInputToVisualConverter},ConverterParameter=3}"></Ellipse>
 </Canvas> 

still if any one as any idea how to incorporate this into the ellipse's Style in order to avoid all this code repeat please let me know . thanks .


Solution

  • I think you need a Multi-binding:

    <Page.Resources>
        <WPFSampleExplorer:MyDiceInputToVisualConverter x:Key="MyDiceInputToVisualConverter" />
        <Style TargetType="{x:Type Ellipse}">
            <Setter Property="Visibility">
                <Setter.Value>
                    <MultiBinding Converter="{StaticResource MyDiceInputToVisualConverter}">
                        <Binding RelativeSource="{RelativeSource Self}" Path="Tag"/>
                        <Binding />
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style>
    </Page.Resources>
    
    <Page.DataContext>
        <Samples:DiceViewModel/>
    </Page.DataContext>
    
    <Canvas>
        <Ellipse Tag="1" Canvas.Left="5" Canvas.Top="5" Width="20" Height="20" Fill="Yellow"></Ellipse>
        <Ellipse Tag="2" Canvas.Left="5" Canvas.Top="20" Width="20" Height="20" Fill="Yellow"></Ellipse>
        <Ellipse Tag="3" Canvas.Left="5" Canvas.Top="35" Width="20" Height="20" Fill="Yellow"></Ellipse>
        <Ellipse Tag="4" Canvas.Left="20" Canvas.Top="20" Width="20" Height="20" Fill="Yellow"></Ellipse>
        <Ellipse Tag="5" Canvas.Left="35" Canvas.Top="5" Width="20" Height="20" Fill="Yellow"></Ellipse>
        <Ellipse Tag="6" Canvas.Left="35" Canvas.Top="20" Width="20" Height="20" Fill="Yellow"></Ellipse>
        <Ellipse Tag="7" Canvas.Left="35" Canvas.Top="35" Width="20" Height="20" Fill="Yellow"></Ellipse>
    </Canvas>
    
    public class DiceViewModel
    {
        // properties here
    }
    
    public class MyDiceInputToVisualConverter : IMultiValueConverter
    {
        #region Implementation of IMultiValueConverter
    
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            Debug.WriteLine(values[0]);  // This outputs 1,2,3,..7
            Debug.WriteLine(values[1]);  // This is your DiceViewModel
    
            return Visibility.Visible;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    
        #endregion
    }