2015-05-06 45 views
0

我正在開發執行項目列表檢查的應用程序。每個項目都有需要在其上執行的檢查的列表。每個檢查可以是以下三種類型之一:CheckBox,ComboBox,TextBox。WPF DataGrid不同的控件在同一列 - 不正確的綁定

我想Datagrid有2列(一個用於項目名稱,第二個用於檢查列表)。第二列包含另一個包含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

只需設置ItemControl的內容屬性:

<ContentControl Content="{Binding}"> 

WPF將自動設置的DataTemplate的DataContext的其父ContentControl中的內容。但是,在您的XAML中,您不設置Content屬性(您只指定ContentControl的樣式,但忘記設置其內容)。

並且不要忘記在您的控件綁定上設置UpdateSourceTrigger=PropertyChanged,否則您可能在視圖模型中看不到更新。

+0

很好的回答!它終於可以工作了:-)謝謝nightcoder,今天我花了很多時間來解決它。 – JacekT

+1

@JacekT,不客氣:)是的,我不喜歡WPF的是,如果你沒有太多的經驗,你可能會浪費很多時間試圖讓它按預期工作。不幸的是,一些(很多?)的東西似乎並不明顯。 – nightcoder

+0

@nightcoder絕對多;) – Mafii