0
votes

I have this dock panel which I'm trying to set up bindings for.

The problem is that my DataContext for my XAML is set to the MainWindow class but my class that I want to bind to (autoCam) is separate from that class. I have an instance of autoCam being used in the MainWindow class, called "myCam", but I've gotten confused about how to get these bindings to work.

This is the code I'm using in my dock panel:

            <DockPanel  x:Name="BottomDock" Visibility="Collapsed" Grid.Column="2" Grid.Row="2" Grid.ColumnSpan="2" DockPanel.Dock="Bottom" Margin="0">
                <Button x:Name="Rewind" Click="Rewind_Click" HorizontalAlignment="Left" Width="23" RenderTransformOrigin="0.5,0.5" Grid.Row="1"/>
                <Button x:Name="Play" Content=">" Click="Play_Click" HorizontalAlignment="Left" Width="17" RenderTransformOrigin="0.5,0.5" Grid.Row="1"/>
                <Button x:Name="Pause" Content="||" Click ="Pause_Click" HorizontalAlignment="Left" VerticalAlignment="Top" Width="16" Height="22" RenderTransformOrigin="0.5,0.5" Grid.Row="1"/>
                <Button x:Name="FastForward" Content=">>" Click="FastForward_Click" HorizontalAlignment="Left" Width="23" RenderTransformOrigin="0.5,0.5" Grid.Row="1"/>
                <TextBlock Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="95" Text="Camera Position"/>
                <TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="cpx" Text="{Binding Path=myCam.cameraPositionX, UpdateSourceTrigger=PropertyChanged}"/>
                <TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="cpy" Text="{Binding Path=myCam.cameraPositionY, UpdateSourceTrigger=PropertyChanged}"/>
                <TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="cpz" Text="{Binding Path=myCam.cameraPositionZ, UpdateSourceTrigger=PropertyChanged}"/>
                <TextBlock Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="95" Text="Look Direction"/>
                <TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="ldx" Text="{Binding Path=myCam.lookDirectionX, UpdateSourceTrigger=PropertyChanged}"/>
                <TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="ldy" Text="{Binding Path=myCam.lookDirectionY, UpdateSourceTrigger=PropertyChanged}"/>
                <TextBox Background="Black" TextAlignment="Center" Foreground="AliceBlue" HorizontalAlignment="Left" Width="40" Name="ldz" Text="{Binding Path=myCam.lookDirectionZ, UpdateSourceTrigger=PropertyChanged}"/>
            </DockPanel>

At first I thought I could just write DataContext=autoCam as a property of the dock panel itself, or for each individual textbox and then just say {binding cameraPositionX} or something, but that didn't do anything.

Then i thought I could just say {Binding myCam.cameraPositionX} since myCam is a member of the MainWindow class. But that didn't work either.

In a futile attempt, I tried to sort of combine both of my guesses and add DataContext=autoCam to properties of all of the text boxes but I never thought that would actually work.

I also tried to write the following after the datacontext=this; line in the mainwindow constructor. I tried this in case the problem was that the xaml would set the datacontext properly as i wanted it, but then the datacontext for the entire ui would be reapplied to the mainwindow when the constructor was run.

    public MainWindow()
    {
        InitializeComponent();
        Interval = new TimeSpan(0, 0, 0, 0, 10);
        Rewind.Content = "<<";
        runType = 2;
        timerRate(runType);
        Loaded += new RoutedEventHandler(MainWindow_Loaded);
        DataContext = this;
        cpx.DataContext = myCam;
        cpy.DataContext = myCam;
        cpx.DataContext = myCam;
        ldx.DataContext = myCam;
        ldy.DataContext = myCam;
        ldz.DataContext = myCam;
        //view1.IsHeadLightEnabled = true;
    }

I thought that maybe I could put this in the Window.Resources XAML:

<Window.Resources>
    <ObjectDataProvider x:Key="Camera" ObjectType="{x:Type local:autoCam}" MethodName="getCamDetails"/>
</Window.Resources>

but i wrote my method getCamDetails in my autoCam class as follows, and it's giving me a null reference exception every time i try to set CamDetails[0] to cameraPositionX.

public class autoCam : INotifyPropertyChanged
{
    MainWindow mW;
    public static double[] CamDetails;

    public static double[] getCamDetails()
    {
        return CamDetails;
    }

    public Point3D cameraPosition
    {
        get { return mC.Position; }
        set
        {
            mC.Position = value;
            cameraPositionX = Convert.ToDouble(cameraPosition.X);
            cameraPositionY = Convert.ToDouble(cameraPosition.Y);
            cameraPositionZ = Convert.ToDouble(cameraPosition.Z);
            lookDirection = mC.LookDirection;
            lookDirectionX = Convert.ToDouble(lookDirection.X);
            lookDirectionY = Convert.ToDouble(lookDirection.Y);
            lookDirectionZ = Convert.ToDouble(lookDirection.Z);
            onPropertyChanged("cameraPosition");
        }
    }
    public double cameraPositionX
    {
        get { return Convert.ToDouble(cameraPosition.X); }
        set { onPropertyChanged("cameraPositionX"); CamDetails[0] = cameraPositionX; }
    }
    public double cameraPositionY
    {
        get { return Convert.ToDouble(cameraPosition.Y); }
        set { onPropertyChanged("cameraPositionY"); CamDetails[1] = cameraPositionY; }
    }
    public double cameraPositionZ
    {
        get { return Convert.ToDouble(cameraPosition.Z); }
        set { onPropertyChanged("cameraPositionZ"); CamDetails[2] = cameraPositionZ; }
    }
    public Vector3D lookDirection
    {
        get { return mC.LookDirection; }
        set {
            mC.LookDirection = value;
            lookDirectionX = Convert.ToDouble(lookDirection.X);
            lookDirectionY = Convert.ToDouble(lookDirection.Y);
            lookDirectionZ = Convert.ToDouble(lookDirection.Z);
            onPropertyChanged("lookDirection");
        }
    }
    public double lookDirectionX
    {
        get { return Convert.ToDouble(lookDirection.X);}
        set { onPropertyChanged("lookDirectionX"); CamDetails[3] = lookDirectionX; }
    }
    public double lookDirectionY
    {
        get { return Convert.ToDouble(lookDirection.Y); }
        set { onPropertyChanged("lookDirectionY"); CamDetails[4] = lookDirectionY; }
    }
    public double lookDirectionZ
    {
        get { return Convert.ToDouble(lookDirection.Z); }
        set { onPropertyChanged("lookDirectionZ"); CamDetails[5] = lookDirectionZ; }

I would really appreciate a solution, but a break down of why these aren't working for me is essentially going to help me a lot more in the long run.

Thank you for your time and help everyone.

1
Where do you initialize CamDetails?nosale

1 Answers

0
votes

It would have been better to share the MainWindow class too but it sounds like putting a property in your MainWindow class to expose the myCam instance and binding directly to that property should work.

public partial class MainWindow : Window
{
    private AutoCam autoCam;

    public AutoCam AutoCam
    {
        get { return autoCam; }
        set { autoCam = value; }
    }


    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        this.autoCam = new AutoCam();
    }
}

public class AutoCam
{
    private string someText;

    public string SomeText
    {
        get { return someText; }
        set { someText = value; }
    }

    public AutoCam()
    {
        this.SomeText = "Some Text";
    }

}

And the binding will be like this.

<Label Content="{Binding AutoCam.SomeText}">