Aztexnica Ответов: 2

Как подключить кнопку столбца datagrid к команде, не находящейся в ее datacontext?


У меня есть приложение Wpf. с помощью таблицы данных, которая имеет представление коллекции в качестве источника данных.
Как я могу подключить кнопки в строках к команде в основном контексте данных окна? Любая помощь будет оценена по достоинству. Спасибо.

<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>


<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.
            }
        }
    
    }
}


Что я уже пробовал:

Поиск в Google и Msdn. Я попытался подключить кнопку к команде из конструктора. Я думаю, что это как-то связано с "относительным исходным родителем".
Я не очень хорошо знаком с MVVM.

2 Ответов

Рейтинг:
2

Dirk Bahle

Попробуйте использовать DataContextProxy или также известный как BindingProxy:
[WPF] Как привязаться к данным, когда DataContext не наследуется | блог Томаса Левеска .NET[^]


Рейтинг:
14

Clifford Nelson

Используйте следующий код в кнопку:

Command="{Binding DataContext.OkCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"