0

I was trying to solve the following problem (and finally succeeded but probably not in the best way). This is how I tried first:

I am showing a treeview with directories and a checkbox with this WPF code:

<Window.DataContext>
    <local:ViewModel/>
</Window.DataContext>

<Grid>
    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
        <StackPanel.Resources>
            <!-- This Style is applied to all TextBlock elements in the command strip area. -->
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center" />
                <Setter Property="Foreground" Value="#EE000000" />
            </Style>
            <local:ColorConverter x:Key="XcolorConverter" />
        </StackPanel.Resources>
        <TreeView ItemsSource="{Binding View}">
        <TreeView.Resources>
                    <HierarchicalDataTemplate DataType="{x:Type local:Folder}" ItemsSource="{Binding SubFolders}">
                    <StackPanel Orientation="Horizontal" VerticalAlignment="Center">
                        <TextBlock Background="{Binding Path=., Converter={StaticResource XcolorConverter}}" Text="{Binding Name}"/>                            
                        <CheckBox Focusable="False" IsChecked="{Binding IsChecked}"  VerticalAlignment="Center"/>
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
    </TreeView>
    </StackPanel>
</Grid>

What I would need to know in the ColorConverter method Convert, below, is the full directory name to color directories which meet a specific criterium. Parameter "value" is a string with the value (MyNameSpace).Folder. If I inspect "value" in the debugger, I also see "Name" which is the directory name (without the preceding full path) displayed in the Treeview's textbox. However, I can not access value:Name within the program (error CS1061: 'object' does not contain a definition for 'Name', I don't understand why I can see it in the debugger but not access it) nor would it help me as I need the full directory path. Within the ViewModel class/code there's a ForEach assigning the directory names to the ObservableCollection Folder. The object parameter is empty; I know I could add ConverterParameter= in the xaml but don't know how to access the actual displayed directory from within that xaml.

How should I change the WPF so my colorConverter.Convert method can access the (full) directory it is displaying at that moment?

    public ICollectionView View { get => cvs.View; }
    private CollectionViewSource cvs = new CollectionViewSource();
    private ObservableCollection<Folder> col = new ObservableCollection<Folder>();

public class Folder { public string Name { get; set; } public ObservableCollection SubFolders { get; set; } = new ObservableCollection(); }

public partial class ColorConverter : IValueConverter
    {
        private static int count;
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        { // Set color based upon directory, something like if paramater.(directory=c:\\temp")...
            return Brushes.Green;
        }
     }   
Dick
  • 433
  • 5
  • 13
  • Any of these might help you : System.IO.Path.GetDirectoryName()/GetExtension()/GetFileName()/GetFileNameWithoutExtension()/GetFullPath() – Denis Schaf May 26 '21 at 12:33
  • generally i wuld recommend using a valuconverter stat checks if strign contains substring. The substring would be send via converter-parameter. Then add triggers that go like this roughly Textbox-triggers-text-stringcontainssubstring("substring")-value true-background-hotpink – Denis Schaf May 26 '21 at 12:50
  • Thanks Denis, but I know how to get the directory but still I do not know how to get that in the converter parameter, also not after reading your second remark. – Dick May 26 '21 at 12:58
  • Does this answer your question? ['object' does not contain a definition](https://stackoverflow.com/questions/25478131/object-does-not-contain-a-definition) – Peter Duniho May 26 '21 at 16:48
  • _"I don't understand why I can see it in the debugger but not access it"_ -- because the debugger knows things about the object that you failed to tell the actual code in your converter. You need to **cast** the `object` parameter that was passed to your method, so that the compiler knows what type the object actually is. See proposed duplicate. – Peter Duniho May 26 '21 at 16:49
  • Indeed Peter, with your reply and the code below (See comment) it now works, thanks! – Dick May 26 '21 at 21:22

1 Answers1

1

If I understood correctly what you need:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    // Validating the type of incoming value
    if (value is Folder folder)
    {
        // Here we work with the folder variable
        string name = folder.Name;

        // Set color based upon directory, something like if paramater.(directory=c:\\temp")...
        return Brushes.Green;
    }
    // If the received value is not of the Folder type,
    // then the converter returns an undefined value.
    return DependencyProperty.UnsetValue;
}
EldHasp
  • 6,079
  • 2
  • 9
  • 24
  • Thank you all for the replies! I also added a NameFull which is assigned GetFullPath in the ViewModel and when used in the Convert method -string name=folder.NameFull- I can access the full directory. I just couldn't figure out how get the required information while I did see the Name value in the debugger. As your code and Peters remark learn me, casting was what I had to do. Thanks again! – Dick May 26 '21 at 21:16