2015-05-06 3 views
0

Я разрабатываю приложение, выполняющее проверки в списке элементов. Каждый элемент имеет список проверок, которые необходимо выполнить на нем. Каждая проверка может быть одной из трех типов: CheckBox, ComboBox, TextBox.WPF DataGrid различные элементы управления в одном столбце - неправильное связывание

Я хотел бы иметь Datagrid с 2 столбцами (один для названия элемента, второй для списка проверок). Второй столбец содержит другой DataGrid с двумя столбцами (один для имени проверки, второй для контроля проверки). Цель состоит в том, чтобы иметь разные типы элементов управления в одном столбце, связанные с моделями Check.

Проблема заключается в том, что связывание с CheckValue не работает, однако привязки со всеми другими свойствами работают нормально.

Последний столбец содержит CheckBoxes, TextBox и ComboBox, однако они не заполнены никакими значениями. Кто-нибудь знает, что не так с кодом ниже?

Ниже приведены примеры типовых классов

public class Item 
{ 
    public string ItemName { get; set; } 
    public ObservableCollection<Check> Checks { get; set; } 

    public Item() 
    { 
     Checks = new ObservableCollection<Check>(); 
    } 
} 

public enum CheckType 
{ 
    CheckBox, 
    ComboBox, 
    TextBox 
} 

public abstract class Check 
{   
    public string CheckName { get; set; } 
    public CheckType CheckType { get; protected set; } 
    public abstract object CheckValue { get; set; } 
} 

public class CheckBox : Check 
{ 
    private bool checkValue; 

    public CheckBox() 
    { 
     CheckType = CheckType.CheckBox; 
    } 

    public override object CheckValue 
    { 
     get 
     { 
      return checkValue; 
     } 
     set 
     { 
      checkValue = (bool)value; 
     } 
    } 
} 

public class ComboBox : Check 
{ 
    private List<string> checkValue; 

    public ComboBox() 
    { 
     CheckType = CheckType.ComboBox; 
    } 

    public override object CheckValue 
    { 
     get 
     { 
      return checkValue; 
     } 
     set 
     { 
      checkValue = value as List<string>; 
     } 
    } 
} 

public class TextBox : Check 
{ 
    private string checkValue; 

    public TextBox() 
    { 
     CheckType = CheckType.TextBox; 
    } 

    public override object CheckValue 
    { 
     get 
     { 
      return checkValue; 
     } 
     set 
     { 
      checkValue = value as string; 
     } 
    } 
} 

public class MainViewModel 
{ 
    public ObservableCollection<Item> Items { get; set; } 

    public MainViewModel() 
    { 
     Items = new ObservableCollection<Item>(); 

     Item item = new Item(); 
     item.ItemName = "First item"; 

     Check check1 = new CheckBox() { CheckName = "Check 1", CheckValue = true }; 
     Check check2 = new CheckBox() { CheckName = "Check 2", CheckValue = false }; 
     Check text1 = new TextBox() { CheckName = "Check 3", CheckValue = "Please enter check" }; 
     Check combo1 = new ComboBox() { CheckName = "Check 4", CheckValue = new List<string> { "Value1", "Value2" } }; 

     item.Checks.Add(check1); 
     item.Checks.Add(check2); 
     item.Checks.Add(text1); 
     item.Checks.Add(combo1); 

     Items.Add(item); 
    } 
} 

И, наконец, вот XAML код главного окна.

<Window x:Class="ItemTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:vm ="clr-namespace:ItemTest" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <vm:MainViewModel x:Key="mainViewModel"/>   
</Window.Resources> 

<Grid DataContext="{Binding Source={StaticResource mainViewModel}}"> 
    <DataGrid ItemsSource="{Binding Path=Items}" AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="Item" Binding="{Binding ItemName}" /> 
      <DataGridTemplateColumn Header="Checks"> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <DataGrid ItemsSource="{Binding Checks}" AutoGenerateColumns="False" HeadersVisibility="None"> 
          <DataGrid.Columns> 
           <DataGridTextColumn Binding="{Binding CheckName}" /> 
           <DataGridTemplateColumn> 
            <DataGridTemplateColumn.CellTemplate> 
             <DataTemplate> 
              <ContentControl> 
               <ContentControl.Style> 
                <Style TargetType="ContentControl"> 
                 <Style.Triggers> 
                  <DataTrigger Binding="{Binding CheckType}" Value="CheckBox"> 
                   <Setter Property="ContentTemplate"> 
                    <Setter.Value> 
                     <DataTemplate> 
                      <CheckBox IsChecked="{Binding CheckValue}"/> 
                     </DataTemplate> 
                    </Setter.Value> 
                   </Setter> 
                  </DataTrigger> 
                  <DataTrigger Binding="{Binding CheckType}" Value="ComboBox"> 
                   <Setter Property="ContentTemplate"> 
                    <Setter.Value> 
                     <DataTemplate> 
                      <ComboBox ItemsSource="{Binding CheckValue}" /> 
                     </DataTemplate> 
                    </Setter.Value> 
                   </Setter> 
                  </DataTrigger> 
                  <DataTrigger Binding="{Binding CheckType}" Value="TextBox"> 
                   <Setter Property="ContentTemplate"> 
                    <Setter.Value> 
                     <DataTemplate> 
                      <TextBox Text="{Binding CheckValue}" /> 
                     </DataTemplate> 
                    </Setter.Value> 
                   </Setter> 
                  </DataTrigger> 
                 </Style.Triggers> 
                </Style> 
               </ContentControl.Style> 
              </ContentControl> 
             </DataTemplate> 
            </DataGridTemplateColumn.CellTemplate> 
           </DataGridTemplateColumn> 
          </DataGrid.Columns> 
         </DataGrid> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
</Grid> 

ответ

1

Просто установите Content собственность ItemControl в:

<ContentControl Content="{Binding}"> 

WPF автоматически установит DataContext DataTemplate для родительского содержания ContentControl в. Но в вашем XAML вы не устанавливаете свойство Content (вы указываете только стиль ContentControl, но не забудьте установить его содержимое).

И не забудьте установить UpdateSourceTrigger=PropertyChanged на свои контрольные привязки, иначе вы не увидите обновлений в своей модели просмотра.

+0

Отличный ответ! Это, в конце концов, работает :-) Спасибо ночной кодер, я потратил так много времени, чтобы решить эту проблему. – JacekT

+1

@ JacekT, приветствую вас :) И да, что мне не нравится в WPF, так это то, что если у вас мало опыта, вы можете потратить много времени, пытаясь заставить его работать должным образом. К сожалению, некоторые (многие?) Вещи не кажутся очевидными. – nightcoder

+0

@ nightcoder определенно много;) – Mafii

Смежные вопросы