简体   繁体   English

Datagrid组合框选择项值与文本框的绑定

[英]Datagrid Combobox Seletected item Value to Textbox binding

Hope you are doing well and coding as Guru. 希望您一切顺利,并以Guru编码。

Here comes Datagrid binding problem which is pain for me for 2 days. Datagrid绑定问题来了,这让我痛苦了两天。 I asked other other question related to this problem and solved it, but here is other one. 我问了与此问题有关的其他问题,并解决了这个问题,但这是另一个问题。

I have RawVal struct and Signal class(has ObservableCollection). 我有RawVal结构和信号类(具有ObservableCollection)。

public struct RawVal
{
    public string name { get; set; }
    public int value { get; set; }
}

public class Signal
{
    public string Name { get; set; }
    public Int32 Value { get; set; }
   public ObservableCollection<RawVal> rawValue { get; set; }
}

And now XAML looks like 现在XAML看起来像

<DataGrid ItemsSource="{Binding}" Name="grdSignal" Grid.Row="1" CanUserAddRows="False" AutoGenerateColumns="False" SelectionChanged="grdSignal_SelectionChanged_1">
     <DataGrid.Columns>
        <DataGridTextColumn Header="            Signal Name" Binding="{Binding Name}" Width="150"/>
           <DataGridTemplateColumn Header="   Physical Value " Width="100">
              <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                      <ComboBox ItemsSource="{Binding rawValue}" SelectedItem="Binding name"  DisplayMemberPath="name" Name="cmbVal" SelectedIndex="0" 
                             Visibility="{Binding Path=rawValue.Count, Converter={StaticResource ComboBoxItemCountToEnabledConverter}}"/>
                 </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
            <DataGridTemplateColumn Header="    Value " Width="100">
                <DataGridTemplateColumn.CellTemplate>
                   <DataTemplate>
                       <TextBox Text="{Binding }" />
                   </DataTemplate>
               </DataGridTemplateColumn.CellTemplate>
          </DataGridTemplateColumn>
        </DataGrid.Columns>
     </DataGrid> 

UI with binding 具有绑定的UI

Problem is when user selects any item from Physical Value Combobox, value related to this item needs to be shown in Value textbox. 问题是当用户从“物理值组合”框中选择任何项目时,与此项目相关的值需要显示在“值”文本框中。

For example, RawVal in Signal class contains these values. 例如,Signal类中的RawVal包含这些值。

4 - Search Key Trigger
3 - Tailgate Key Trigger
2 - Un-Lock Key Trigger 
1 - Lock Key Trigger
0 - No Remote RQ Trigger

When user selects "Tailgate Key Trigger", 3 appears in textbox. 当用户选择“尾门按键触发器”时,文本框中将出现3。 When "No Remote RQ Trigger" selected, 0. 选择“无远程RQ触发器”时,为0。

Any suggestions and solutions are welcomed, Thank you. 欢迎任何建议和解决方案,谢谢。

I have created a simple solution based on MVVM to just guide you how can it be done. 我创建了一个基于MVVM的简单解决方案,以指导您如何完成它。

ViewModel class ViewModel类

class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private ObservableCollection<Signal> _source;
    public IEnumerable<Signal> MySource
    {
        get { return _source; }
    }

    private RawVal _rawValSelected;
    public RawVal RawValSelected
    {
        get { return _rawValSelected; }
        set
        {
            _rawValSelected = value;

            RaisePropertyChanged("RawValSelected");
        }
    }

    public void RaisePropertyChanged(string propName)
    {
        var pc = PropertyChanged;
        if (pc != null)
        {
            pc(this, new PropertyChangedEventArgs(propName));
        }
    }

    public ViewModel()
    {
        _source = new ObservableCollection<Signal>
        {
            new Signal{
                Name = "Test",
                Value = 1,
                rawValue = new ObservableCollection<RawVal>
                {
                    new RawVal{name="Search Key Trigger",value=4},
                    new RawVal{name="Tailgate Key Trigger",value=3},
                    new RawVal{name="Un-Lock Key Trigger",value=2},
                    new RawVal{name="Lock Key Trigger",value=1},
                    new RawVal{name="No Remote RQ Trigger",value=0}
                }
            }
        };
    }
}

The view 风景

<DataGrid ItemsSource="{Binding MySource}" Name="grdSignal" CanUserAddRows="False" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Signal Name" Binding="{Binding Name}" Width="150" />
        <DataGridTemplateColumn Header="Physical Value " Width="100">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding rawValue}"
                              SelectedItem="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}},Path=DataContext.RawValSelected}"
                              DisplayMemberPath="name" SelectedIndex="0" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="Value" Width="100">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}},Path=DataContext.RawValSelected.value}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

I removed some of your code since I don't have the converter code Note the use of RelativeSource which helps me bind the selected value of the combobox to a property in the view model 由于没有转换器代码,因此删除了一些代码。请注意,使用RelativeSource可帮助我将组合框的选定值绑定到视图模型中的属性

The code behind of the view 视图背后的代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}

You have to have INotifyPropertyChanged event implemented for Signal , and use SelectedItem property of your Combobox to set the value for TextBox column. 您必须为Signal实现INotifyPropertyChanged事件,并使用Combobox SelectedItem属性设置TextBox列的值。

Xaml code : XAML代码:

<DataGrid ItemsSource="{Binding}" Name="grdSignal" Grid.Row="1" CanUserAddRows="False" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="            Signal Name" Binding="{Binding Name}" Width="150"/>
        <DataGridTemplateColumn Header="   Physical Value " Width="100">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox  ItemsSource="{Binding rawValue, Mode=OneWay}" SelectedItem="{Binding SelectedRaValue, Mode=TwoWay,  UpdateSourceTrigger=PropertyChanged}"  DisplayMemberPath="name" Name="cmbVal"
                             Visibility="{Binding Path=rawValue.Count, Converter={StaticResource ComboBoxItemCountToEnabledConverter}}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
        <DataGridTemplateColumn Header="    Value " Width="100">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding ComboValue}"  />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

C# / code behind C#/代码落后

public class Signal: INotifyPropertyChanged 
{
    public string Name 
    {
        get;
        set;
    }
    public Int32 Value 
    {
        get;
        set;
    }
    private ObservableCollection < RawVal > rawValue1;
    public ObservableCollection < RawVal > rawValue 
    {
        get 
        {
            return rawValue1;
        }
        set 
        {
            rawValue1 = value;
            OnPropertyChanged("rawValue");
            if (value != null && value.Count > 0) 
            {
                SelectedRaValue = value.First();
            }
        }
    }

    private RawVal selectedRaValue;
    public RawVal SelectedRaValue 
    {
        get 
        {
            return selectedRaValue;
        }
        set 
        {
            selectedRaValue = value;
            OnPropertyChanged("SelectedRaValue");
            ComboValue = value.name;
            OnPropertyChanged("ComboValue");
        }
    }

    public string ComboValue 
    {
        get;
        set;
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName) 
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

Now you can set your DataContext 现在您可以设置DataContext

 List < Signal > collection = new List < Signal > ();
 collection.AddRange((new[] 
 {
    new Signal
    {
        Name = "Hello",
        Value = 1,
        rawValue = new ObservableCollection < RawVal > ((new[] {
            new RawVal { name = "A", value = 1}, 
            new RawVal {name = "B", value = 1}
        }).ToList()),
    },
    new Signal {
        Name = "World",
        Value = 2,
        rawValue = new ObservableCollection < RawVal > ((new[] {
            new RawVal {name = "A", value = 1}, 
            new RawVal {name = "B", value = 1}
        }).ToList()),
    }
 }).ToList());

 this.DataContext = collection;

Hope this helps !! 希望这可以帮助 !!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM