junsuchoi
junsuchoi

Reputation: 41

binding can only be set in dependencyproperty of dependencyobject

<Window x:Class="Kiosk.DeleteMenu.DeleteMenuWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Kiosk.DeleteMenu"
        mc:Ignorable="d"
        Title="DeleteMenuWindow" Height="800" Width="800">
    <Grid>

        <ListBox ItemsSource="{Binding Menus}" Width="800">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Width="800"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="1" BorderBrush="Black" Width="250" Background="Transparent">
                        <StackPanel Orientation="Vertical" Width="250">
                            <StackPanel.InputBindings>
                                <MouseBinding MouseAction="LeftClick" Command="{Binding StackPanelClickCommands}"  CommandParameter="{Binding ElementName=lb_MenuText, Path=Content}"></MouseBinding>
                            </StackPanel.InputBindings>
                            <Image Width ="150" Height="150" Stretch="Uniform" StretchDirection="Both" Source="{Binding Path = MenuImagetoBS}">
                            </Image>
                            <Border BorderThickness="1" BorderBrush="Silver">
                                <Label x:Name ="lb_MenuText" Content="{Binding Path = MenuText}"></Label>
                            </Border>
                            <Label Content="{Binding Path = MenuKind}"></Label>
                        </StackPanel>
                    </Border>
                </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
    </Grid>
</Window>

Here is my xaml source code. I get an error saying binding can only be set in dependency property of dependency object. But I don't know what caused it. I don't understand why I need a way to add dependencies to my code

Nothing special, just adding to the stackpanel

    <Image.InputBindings>
    <MouseBinding MouseAction="LeftClick" Command="{Binding StackPanelClickCommands}"  CommandParameter="{Binding ElementName=lb_MenuText, Path=Content}"></MouseBinding>
    </Image.InputBindings>

Even if I remove it from the stack panel and apply it to the image, the error is the same


<Image Margin="757,222,312,373">
        <Image.Resources>
            <Style TargetType="{x:Type Image}">
                <!-- Default image -->
                <Setter Property="Source" Value="Resources/DefaultPoint.png"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <!-- Hover image -->
                        <Setter Property="Source" Value="Resources/MapPoint.png"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Image.Resources>
        <Image.ToolTip>
            <ToolTip x:Name="USToolTip2" Width="250">
                <StackPanel Background="White" Width="250">
                    <TextBlock FontWeight="Bold" Width="{Binding ActualWidth, ElementName=USToolTip}"><Run  Foreground="Red" Text=" : " /><Run Text=" "/><Run  Foreground="Black" Text="{Binding Covid.Country}"/></TextBlock>
                    <TextBlock FontWeight="Bold"><Run  Foreground="Red" Text=": "/><Run Text=" "/><Run  Foreground="Black" Text="{Binding Covid.Confirmedcase}"/></TextBlock>
                    <TextBlock FontWeight="Bold"><Run  Foreground="Red" Text=": "/><Run Text=" "/><Run  Foreground="Black" Text="{Binding Covid.Dead}"/></TextBlock>
                    <TextBlock FontWeight="Bold"><Run  Foreground="Red" Text=": "/><Run Text=" "/><Run  Foreground="Black" Text="{Binding Covid.Cured}"/></TextBlock>
                    <TextBlock FontWeight="Bold"><Run  Foreground="Red" Text=": "/><Run Text=" "/><Run  Foreground="Black" Text="{Binding Covid.Fatality}"/></TextBlock>
                    <TextBlock FontWeight="Bold"><Run  Foreground="Red" Text=": "/><Run Text=" "/><Run  Foreground="Black" Text="{Binding Covid.CuredPercent}"/></TextBlock>
                    <TextBlock FontWeight="Bold"><Run  Foreground="Red" Text=": "/><Run Text=" "/><Run  Foreground="Black" Text="{Binding Covid.Incidence}"/></TextBlock>
                </StackPanel>
            </ToolTip>
        </Image.ToolTip>
        <Image.InputBindings>
            <MouseBinding MouseAction="LeftClick" Command="{Binding MapPointCommand}" CommandParameter="🇮🇳"/>

        </Image.InputBindings>

This code I used in another project works. I don't know why the error pops up even if I apply it to the same image element. Help

Upvotes: 0

Views: 112

Answers (1)

Andy
Andy

Reputation: 12276

One problem here seems to be because you don't understand what a label is in wpf. You should probably be using a textblock instead.

When you bind the content property of a label to a string, what happens is the code in the label adds a textblock to it's content and sets the text property of that textblock to the string. The content becomes a textblock.

If you try binding to the content of that label then you get a TextBlock rather than the string you're expecting.

I don't follow why you decided to use elementname binding, you can just bind to the menutext property in the datacontext:

        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border BorderThickness="1" BorderBrush="Black" Width="250" Background="Transparent">
                    <StackPanel Orientation="Vertical" Width="250">
                        <StackPanel.InputBindings>
                            <MouseBinding MouseAction="LeftClick" 
                                          Command="{Binding StackPanelClickCommands}"  
                                          CommandParameter="{Binding MenuText}"/>
                        </StackPanel.InputBindings>
                        <Image Width ="150" Height="150" Stretch="Uniform" StretchDirection="Both" Source="{Binding Path = MenuImagetoBS}">
                        </Image>
                        <Border BorderThickness="1" BorderBrush="Silver">
                            <Label x:Name ="lb_MenuText" Content="{Binding MenuText}"></Label>
                        </Border>
                        <Label Content="{Binding Path = MenuKind}"></Label>
                    </StackPanel>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>

With wpf, a button is a content control and you can put pretty much anything you like in it. Buttons are designed to handle clicks and bind to commands so are a better option than mousebinding on a stackpanel.

I tried this code out using the community mvvm toolkit:

My window

    <Window.DataContext>
            <local:MainWindowViewModel/>
    </Window.DataContext>
    <Grid>
        <ListBox ItemsSource="{Binding Items}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="1" BorderBrush="Black" Width="250" Background="Transparent">
                        <Button Command="{Binding StackPanelClickCommand}"  
                                CommandParameter="{Binding MenuText}">
                            <StackPanel Orientation="Vertical" 
                                        Width="250">
                                <Image Width ="150" Height="150" Stretch="Uniform" StretchDirection="Both" Source="{Binding Path = MenuImagetoBS}">
                                </Image>
                                <Border BorderThickness="1" BorderBrush="Silver">
                                    <Label x:Name ="lb_MenuText" Content="{Binding MenuText}"></Label>
                                </Border>
                                <Label Content="{Binding MenuKind}"></Label>
                            </StackPanel>
                        </Button>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

Viewmodel for that:

    public partial class MainWindowViewModel : ObservableObject
    {

        [ObservableProperty]
        private ObservableCollection<ItemViewModel> items = new ObservableCollection<ItemViewModel>();

        public MainWindowViewModel()
        {
              Items = new ObservableCollection<ItemViewModel>(
              new List<ItemViewModel>{
                  new ItemViewModel{  MenuKind = "A", MenuText = "AA"},
                  new ItemViewModel {  MenuKind = "B", MenuText = "BB"},
                  new ItemViewModel {  MenuKind = "C", MenuText = "CC" }
              });
        }
    }

ItemViewModel

public partial class ItemViewModel : ObservableObject
{
    [ObservableProperty]
    private string menuKind;

    [ObservableProperty]
    private string menuText;
    [RelayCommand]
    private void StackPanelClick(string menutext)
    {
        // I just put a break point on the opening bracket to test this
    }
}

This works as expected. No errors. Put a break point in that relaycommand and it's reached when I click.

The parameter to the command is kind of pointless because the property is in the same class so it could be referenced without a problem by my command.

If I then change it back to a mousebinding on the stackpanel I can make that work as well.

I gave the stackpanel a background as I don't have your picture.

                <DataTemplate>
                    <Border BorderThickness="1" BorderBrush="Black" Width="250" Background="Transparent">
                        <!--<Button Command="{Binding StackPanelClickCommand}"  
                                CommandParameter="{Binding MenuText}">-->
                            <StackPanel Orientation="Vertical" 
                                        Width="250"
                                        Background="Transparent">
                        <StackPanel.InputBindings>
                            <MouseBinding MouseAction="LeftClick" Command="{Binding StackPanelClickCommand}"
                                          CommandParameter="{Binding MenuText}">
                                
                            </MouseBinding>
                        </StackPanel.InputBindings>
                        <Image Width ="150" Height="150" Stretch="Uniform" StretchDirection="Both" Source="{Binding Path = MenuImagetoBS}">
                                </Image>
                                <Border BorderThickness="1" BorderBrush="Silver">
                                    <Label x:Name ="lb_MenuText" Content="{Binding MenuText}"></Label>
                                </Border>
                                <Label Content="{Binding MenuKind}"></Label>
                            </StackPanel>
                        <!--</Button>-->
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>

Not sure what else you have in that project but you've not showed us something significant here.

Upvotes: 1

Related Questions