Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I have an Wpf app. with a data grid that has a collection view as its data source.
How can I connect the buttons in the rows to the command in the main data context of the window? Any help appreciated. Thanks.

XML
<pre><Window x:Class="WpfBcApp2.MainWindow"
        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:VModel="clr-namespace:WpfBcApp2.ViewModel"
        mc:Ignorable="d"
        Title="MainWindow" Height="500.53" Width="758.259">

    <Window.DataContext>
        <VModel:MainViewModel x:Name="MVMod"/>
    </Window.DataContext>
    
    <Window.Resources>
        <CollectionViewSource x:Name="MtlColView" x:Key="cvsMtrls" Source="{Binding OcMaterial}" Filter="ShowOnlyFilter"/>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="240"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid Grid.Column="1" Margin="10">
            <Grid.RowDefinitions>
                <RowDefinition Height="155"/>
                <RowDefinition/>
            </Grid.RowDefinitions>

            <DataGrid x:Name="mTableDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding Source={StaticResource cvsMtrls}}" Margin="10" Grid.Row="1" RowDetailsVisibilityMode="VisibleWhenSelected" Padding="1,0" HeadersVisibility="Column" CanUserDeleteRows="False" CanUserAddRows="False" >
                <DataGrid.Columns>
                    <DataGridTextColumn x:Name="shapeColumn" Binding="{Binding Shape}" Header="Shape"/>
                    <DataGridTextColumn x:Name="typeColumn" Binding="{Binding Type}" Header="Type"/>
                    <DataGridTextColumn x:Name="matNumColumn" Binding="{Binding MatNum}" Header="Mat Num"/>
                    <DataGridTextColumn x:Name="descColumn" Binding="{Binding Desc}" Header="Desc" Width="*"/>
                    <DataGridTextColumn x:Name="widthColumn" Binding="{Binding Width}" Header="Width"/>
                    <DataGridTextColumn x:Name="lengthColumn" Binding="{Binding Length}" Header="Length"/>
                    <DataGridTextColumn x:Name="sizeColumn" Binding="{Binding Height}" Header="Height"/>
                    <DataGridTemplateColumn Header="Add" MinWidth="45">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button x:Name="DgBtnAdd" Content="Add" Click="DgBtnAdd_Click"></Button>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>

            <ListBox x:Name="ListType" HorizontalAlignment="Left" Margin="10,41,0,10" Width="105" SelectionChanged="ListType_SelectionChanged" ItemsSource="{Binding OcShapes}"></ListBox>
            <ListBox x:Name="ListMat" HorizontalAlignment="Left" Margin="120,41,0,10" Width="102" SelectionChanged="ListMat_SelectionChanged" ItemsSource="{Binding OcMTypes}"></ListBox>
            <ListBox x:Name="ListMach" HorizontalAlignment="Left" Margin="227,41,0,10" Width="164" ItemsSource="{Binding OcMachines}" SelectionChanged="ListMach_SelectionChanged" SelectedItem="{Binding SelMach}"></ListBox>
           
            <Button x:Name="BtnReset" Content="Reset" Margin="0,123,10,10" Click="BtnReset_Click" HorizontalAlignment="Right" Width="72"/>
            <Label Content="Shape" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="26" Width="45"/>
            <Label Content="Type" HorizontalAlignment="Left" Margin="120,10,0,0" VerticalAlignment="Top" Height="26" Width="45"/>
            <Label Content="MachList" HorizontalAlignment="Left" Margin="227,10,0,0" VerticalAlignment="Top" Width="56"/>

        </Grid>

        <Image x:Name="ImgBox" Height="207" VerticalAlignment="Top" Margin="10,41,10,0" Source="{Binding CurImage}"/>
        <Label Content="Current QrCode" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>

    </Grid>

</Window>


C#
<pre>using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using WpfBcApp2.Model;
using System.IO;
using System.Windows.Input;
using System.Drawing;
using System.Data;

namespace WpfBcApp2.ViewModel
{
    public class MainViewModel : ModelBase
    {
        //
        public MatListDataSet1 MLDataSet = new MatListDataSet1();
        public ObservableCollection<MTypes> OcMTypes { get; set; }
        public ObservableCollection<Shapes> OcShapes { get; set; }
        public ObservableCollection<Material> OcMaterial { get; set; }
        public ObservableCollection<Machine> OcMachines { get; set; }
        //
        private const string Mpath = @"C:\Users\...\Desktop\MLDataSet.xml";
        string TempPath = @"C:\Users\...\Desktop\TestMats.csv";
        private const string MachListpath = @"C:\Users\...\Desktop\MachList.txt";
        //
        public RelCom BcImgCom { get; set; }
        private RepClass.RepClass repClass;
        public Bitmap CurImage { get; set; }
        public Machine SelMach { get; set; }


        public MainViewModel()
        {
            // Initialize instance of the Report class...
            repClass = new RepClass.RepClass();
            //
            OcMaterial = new ObservableCollection<Material>();
            Material Mat = null;
            //
            if (File.Exists(Mpath))
                MLDataSet.ReadXml(Mpath);
            //
            foreach (MatListDataSet1.MatListRow MLRow in MLDataSet.MatList)
            {
                Mat = new Material();
                //
                if (!MLRow.IsShapeNull())
                    Mat.Shape = MLRow.Shape;
                //
                if (!MLRow.IsTypeNull())
                    Mat.Type = MLRow.Type;
                //
                Mat.MatNum = MLRow.MatNum;
                //
                if (!MLRow.IsDescNull())
                    Mat.Desc = MLRow.Desc;
                //
                if (!MLRow.IsWidthNull())
                    Mat.Width = MLRow.Width;
                else
                    Mat.Width = "1";
                //
                if (!MLRow.IsLengthNull())
                    Mat.Length = MLRow.Length;
                //
                if (!MLRow.IsHeightNull())
                    Mat.Height = MLRow.Height;
                //
                if (!MLRow.IsFeedRateNull())
                    Mat.FeedRate = MLRow.FeedRate;
                //
                OcMaterial.Add(Mat);
                //
            }
            //
            if (File.Exists(Mpath))
                MLDataSet.WriteXml(Mpath);
            //
            OcMTypes = new ObservableCollection<MTypes>();
            OcShapes = new ObservableCollection<Shapes>();
            //
            IEnumerable<string> Mvals = OcMaterial.Where(m => m.Type != null).Select(m => m.Type).Distinct().ToList();
            //
            foreach (string mval in Mvals)
            {
                OcMTypes.Add(new MTypes(mval));
            }
            //
            IEnumerable<string> Svals = OcMaterial.Select(m => m.Shape).Distinct().ToList();
            //
            foreach (string shape in Svals) // Was foreach in These
            {
                OcShapes.Add(new Shapes(shape));
            }
            //
            OcMachines = new ObservableCollection<Machine>();
            using (StreamReader reader = new StreamReader(MachListpath))
            {
                string line;
                while ((line = reader.ReadLine()) != null)
                {
                    if (!string.IsNullOrWhiteSpace(line))
                    {
                        OcMachines.Add(new Machine(line.Split(',')[0].Trim(), line.Split(',')[1].Trim()));
                    }
                }
            }
            //
        }

    
        public bool AddMat_CanExecute(object parameter)
        {
            return true;
        }


        public void GetBcImage(object selectedItem)
        {
            if (selectedItem != null)
            {
                var Mat = selectedItem as Material;
                CurImage = repClass.GetBcImg(repClass.GenBcString(SelMach.RoutNum, Mat.MatNum, Mat.Height, Mat.Width, Mat.Length, Mat.FeedRate), out string Err); // Set the image source.
            }
        }
    
    }
}


What I have tried:

Google and Msdn searches. I have tried to connect the button to the command from within the designer. I think it has something to do with "Relative source parent".
I'm not that familiar with MVVM.
Posted
Updated 19-Apr-18 2:00am

Use the following XAML within the Button:

Command="{Binding DataContext.OkCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
 
Share this answer
 
Try using a DataContextProxy or also known as BindingProxy:
[WPF] How to bind to data when the DataContext is not inherited | Thomas Levesque's .NET blog[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900