-1

I've been breaking my head on best approach to this for few weeks now, and I need some doubts cleared for me, since there are many places I'm unsure as to what's the correct method of binding.

I'm working on a small app for autocad (using its api), and to speed up debuging, I'm simulating it with cmd;

the app creates an instance of my model, and the model instantiates my_window.

in the model, I have ObservableCollection "window_display_data" thats supposed to populate a datagrid in WPF.

I'm aware I can use codebehind, to set datacontext, but I'm also aware that to use the "property panel preview" , its best to set datacontext from "markup code", so thats what I'm trying to do.

I was able to "by accident" populate the table, but in that case, I was setting my observable collection to "static", which I dont see recomended anywhere... so please, someone give me a review of the code, and what would be prefered path to binding my grid.

my "acad simulator"

public static void Main()
{
    MyCommands start = new MyCommands();
    start.model();
}

public partial class MyCommands
{
    public ObservableCollection<string> window_display_data { get; set; }        

    public void model()
    {
        .....test values initialization...

        MainWindow _window = new MainWindow(this);
        var application = new System.Windows.Application();
        application.Run(_window);
    }
}

public partial class MainWindow : Window
{
    public static MyCommands myModel { get; set; }

    public MainWindow(MyCommands model)
    {

        myModel = new MyCommands();
        myModel= model;
        InitializeComponent();
        //this.DataContext = myModel;
    }
}

my "window"

<Window
    x:Name="MainWindowName" 
    x:Class="_2017_test_binding.MainWindow"     
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:local="local" 
    xmlns:local1="clr-namespace:_2017_test_binding"    
    xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    Title="MainWindow" Height="220" Width="200" WindowStartupLocation="CenterOwner" 
    ResizeMode="CanResizeWithGrip" MouseDown="Window_MouseDown" Topmost="True"    
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
    <DataGrid x:Name="dataGrid" HorizontalAlignment="Left" Width="192"
              GridLinesVisibility="Horizontal" AutoGenerateColumns="False" 
              ItemsSource="{Binding ElementName=MainWindowName, Path=myDictionary}">

        <DataGrid.Columns >
            <DataGridTextColumn Header="Command" Binding="{Binding Mode=OneWay, Path=window_display_data}"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

I guess I should set the dataContext in the window, and let it trinkle down to dataGrid; But without debuging, I never know what ends up down there.

also, could someone clear up for me, why the "dataContext window in property panel in VS" shows links to "objects" instead of instances? that confuses me completely, since what use do I have from that link, if my instance is doing all the work.

enter image description here

John Stritenberger
  • 1,194
  • 1
  • 12
  • 30

1 Answers1

1

Experienced developers that knows about XAML and the MVVM design pattern almost never use the property panel in the Visual Studio to set properties I would say. Personally I almost never use the designer at all. You should really learn XAML if you are serious about WPF.

You can set a property in both XAML and code. In this case where you inject the MainWindow with an instance of your MyCommands class, you could set the DataContext of the window to the MyCommands object and then bind directly to the ObservableCollection<string>:

public partial class MainWindow : Window
{
    private readonly MyCommands _myModel;

    public MainWindow(MyCommands model)
    {
        _myModel = model;
        InitializeComponent();
        this.DataContext = _myModel;
    }
}

<Window
    x:Name="MainWindowName" 
    x:Class="_2017_test_binding.MainWindow"     
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:local="local" 
    xmlns:local1="clr-namespace:_2017_test_binding"    
    xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    Title="MainWindow" Height="220" Width="200" WindowStartupLocation="CenterOwner" 
    ResizeMode="CanResizeWithGrip" MouseDown="Window_MouseDown" Topmost="True">
    <Grid>
        <DataGrid x:Name="dataGrid" HorizontalAlignment="Left" Width="192"
              GridLinesVisibility="Horizontal" AutoGenerateColumns="False" 
              ItemsSource="{Binding window_display_data}">
            <DataGrid.Columns >
                <DataGridTextColumn Header="Command" Binding="{Binding}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

The DataGrid inherits the DataContext (MyCommands) from the window and binds to the window_display_data property. The DataGridTextColumn then binds to the strings in the ItemsSource.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • thank you for your reply. I know that for professionals, the "binding question" must be annoying (saw there's a bunch of threads on the subject); Its just that most of them take on different approaches, which adds to confusion to newbies. I know that I can use this.DataContext=_model; but I commented it out because I've read that such approach might not work or display preview during design time. But I think you are right; I'll just stick to behindCode method of binding until I'm more confident with my self to do it directly in XML; – Lucano Deskovic Apr 09 '17 at 12:46
  • To get design time support you could set the d:DataContext attribute of the window as suggested here: http://stackoverflow.com/questions/1889966/what-approaches-are-available-to-dummy-design-time-data-in-wpf. I would spend to much time on design time issues though. There are certainly cases that the designer in Visual Studio just can't handle and there is not much you can do about this. – mm8 Apr 09 '17 at 13:24
  • thanks. I knew about the attribute but I thought that it wont work if dataContext is implemented in codebehind. Thats why I was forcing my self to do the whole work in xaml; Hence I was forcing my self to do whole binding in xaml. – Lucano Deskovic Apr 09 '17 at 13:30
  • The design time data context is not related to "real" DataContext. It's just a design time "dummy" context. – mm8 Apr 09 '17 at 13:31
  • thank you. As for the design time context, any sort of preview is good for learning purposes. I'm an amateur/hobbyist, so any sort of preview helps. – Lucano Deskovic Apr 09 '17 at 20:43