0

Everything I've looked at on ComboBox binding shows different implementations than what I'm attempting to do, and my attempts at configuring it myself have failed.

Here's a simplistic example of what I'm trying to accomplish.

Code file:

namespace TestApp
{
    public record ItemInfo
    {
        public int ID;
        public string name;
        public string description;
        public decimal value;
        public bool available;
    }

    public static class Data
    {
        public static ItemInfo[] myItems = new ItemInfo[10];
    }
}

XAML:

<Window
        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:TestApp"
        x:Class="TestApp.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.DataContext>
            <Binding Source="local:Data"/>
        </Grid.DataContext>
        <ComboBox Grid.Row="0"
                  VerticalAlignment="Center" HorizontalAlignment="Center"
                  Width="400" Height="40"
                  ItemsSource="{Binding myItems[]}" DisplayMemberPath="name">
        </ComboBox>
    </Grid>
</Window>

On a side note, lest there be confusion, I've got a separate method (not shown) that populates the myItems array. I know this is working and contains the desired data, as when the program is running I can put a watch on it and see the proper values in the array.

What I'm attempting to do is to have the ComboBox contain all of the Data.myItems[].name values. The above code shows my most recent attempt to bind it, and while it builds successfully and doesn't throw any errors, the ComboBox is still empty.

There is an intellisense ... error under the myItems[] binding stating "No data context found for Binding myItems{}"

I've also tried moving the myItems[] to the Grid.DataContext -- <Binding Source="local:Data:myItems[]} and set ItemsSource to simply {Binding Path="name"} to no avail.

Also tried creating a static Collection of ItemInfo records, and set the Grid data context binding to that collection.. to no avail

What's the key to binding to static classes/objects?

  • Your code has a number of problems, including that you are using fields (data binding requires **properties**) and that a class itself, even a static one, cannot be the data context. See duplicates for the correct way to implement your code. – Peter Duniho Jun 19 '21 at 17:00

1 Answers1

-1

What's the key to binding to static classes/objects?

1) Getting the value of a static member

In order not to confuse oneself, it is better to make the bindable member a read-only property:

    public static class Data
    {
        public static ItemInfo[] MyItems {get;} = new ItemInfo[10];
    }
        <ComboBox Grid.Row="0"
                  VerticalAlignment="Center" HorizontalAlignment="Center"
                  Width="400" Height="40"
                  ItemsSource="{x:Static local:Data.MyItems}"
                  DisplayMemberPath="name">

You can get the Enum value in the same way.

2) Binding a static property.

Binding means "tracking" changes in the value of the source property. To do this, you need to create a static event.

An example of a static wrapper for a clock and binding to it:

using System.Threading;
    public static class ClockForWpf
    {
        private static readonly Timer timer = new Timer(Tick, null, 0, 10);
 
        private static void Tick(object state)
        {
            Time = DateTime.Now;
            TimeChanged?.Invoke(null, EventArgs.Empty);
        }
        public static event EventHandler TimeChanged;
        public static DateTime Time { get; private set; }
    }
        <TextBlock Text="{Binding Path=(local:ClockForWpf.Time)}"/>
EldHasp
  • 6,079
  • 2
  • 9
  • 24