我有一部分视图是基于 TemplateSelector 的动态视图。但是,绑定不适用于 DataTemplate 中的控件。(控件确实显示在屏幕上,只是内容/文本为空)。我怀疑这是一个 DataContext 问题,但经过大量在线搜索后无法弄清楚。这是我的 XAML:
<Grid>
<Grid.DataContext>
<local:MyViewModel/>
</Grid.DataContext>
<Grid.Resources>
<DataTemplate x:Key="T1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
Text="Music"
Style="{StaticResource ResourceKey=textBlockStyle}" />
<TextBox Grid.Column="1"
Grid.Row="0"
Style="{StaticResource ResourceKey=textBoxStyle}"
Text="{Binding Path=MusicName}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="T2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
Text="Currency"
Style="{StaticResource ResourceKey=textBlockStyle}" />
<ComboBox Grid.Column="1"
Grid.Row="0"
Style="{StaticResource ResourceKey=comboBoxStyle}"
ItemsSource="{Binding Path=Currency_List}"
SelectedItem="{Binding Path=Currency}" />
</Grid>
</DataTemplate>
<local:ProductTypeTemplateSelector T1="{StaticResource ResourceKey=T1}"
T2="{StaticResource ResourceKey=T2}"
x:Key="myTemplateSelector" />
<Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
<RowDefinition Height="40"/>
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<!-- This biding works -->
<TextBlock Grid.Row="0"
Text="{Binding Path=MusicName}"/>
<!-- This biding does not work -->
<ContentControl Grid.Row="1"
Name="ccc"
Content="{Binding Path=Product_Type}"
ContentTemplateSelector="{StaticResource myTemplateSelector}">
</ContentControl>
</Grid>
这是我的视图模型(从技术上讲,它是视图模型和模型混合在一起。我并没有真正实现完整的 MVVM 模式)
public class MyViewModel: INotifyPropertyChanged
{
public MyViewModel()
{
SetLists();
}
protected void SetLists()
{
SetList_Product_Type();
SetList_Currency();
}
protected void SearchAndPopulate()
{
string query = string.Format("select * from dbo.vehicle_attributes where ticker like '%{0}%'", Search_Text);
DataView dv = DAL.ExecuteQuery(query);
if (dv.Count > 0)
{
DataRowView dvr = dv[0];
Vehicle_Id = int.Parse(dvr["vehicle_id"].ToString());
Product_Type = dvr["product_type_name"].ToString();
Vehicle_Name = dvr["vehicle_name"].ToString();
Is_Onshore = dvr["domicile_name"].ToString() == "Onshore";
Currency = dvr["currency"].ToString();
CUSIP = dvr["CUSIP"].ToString();
ISIN = dvr["isin"].ToString();
Ticker = dvr["ticker"].ToString();
Valoren = dvr["valoren"].ToString();
PC_Class = PC_Class_List.Find(x => x.Class_Name == dvr["class_name"].ToString());
Implementation_Type = Implementation_Type_List.Find ( x => x.Implementation_Type_Name == dvr["implementation_type_name"].ToString());
Price_Frequency = Price_Frequency_List.Find( x => x.Price_Frequency_Name == dvr["price_freq_name"].ToString());
Status = Status_List.Find( x => x.Status_Name == dvr["status_name"].ToString());
if (!string.IsNullOrEmpty(dvr["last_status_update"].ToString()))
{
Status_Date = DateTime.Parse(dvr["last_status_update"].ToString());
}
else
{
Status_Date = DateTime.MinValue;
}
switch (Product_Type)
{
case "Mutual Fund":
query = string.Format("select lf.dividend_currency, i.ticker from dbo.liquid_funds lf " +
"left join dbo.vehicles i on i.vehicle_id = lf.index_id " +
"where lf.vehicle_id ='{0}'",Vehicle_Id);
DataView dv_mutual_fund = DAL.ExecuteQuery(query);
if(dv_mutual_fund.Count > 0)
{
DataRowView dvr_mutual_fund = dv_mutual_fund[0];
Dividend_Currency = dvr_mutual_fund["dividend_currency"].ToString();
Benchmark_Ticker = dvr_mutual_fund["ticker"].ToString();
}
break;
default:
break;
}
}
}
public ICommand SearchVehicleCommand
{
get
{
return new Command.DelegateCommand(SearchAndPopulate);
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
//ProductType
protected List<string> _product_Type_List = new List<string>();
public List<string> Product_Type_List
{
get
{
return _product_Type_List;
}
set
{
_product_Type_List = value;
OnPropertyChanged("Product_Type_List");
}
}
protected void SetList_Product_Type()
{
string query = "SELECT * FROM dbo.product_types WHERE is_enabled = 1";
DataView dv = DAL.ExecuteQuery(query);
List<string> l = new List<string>();
for (int i = 0; i < dv.Count; i++)
{
l.Add(dv[i]["product_type_name"].ToString());
}
Product_Type_List = l;
}
protected string _product_type;
public string Product_Type
{
get
{
return _product_type;
}
set
{
_product_type = value;
OnPropertyChanged("Product_Type");
SetList_Implementation_Type();
}
}
//Currency
protected List<string> _currency_List = new List<string>();
public List<string> Currency_List
{
get
{
return _currency_List;
}
set
{
_currency_List = value;
OnPropertyChanged("Currency_List");
}
}
protected void SetList_Currency()
{
string query = "SELECT currency FROM dbo.currencies";
DataView dv = DAL.ExecuteQuery(query);
List<string> l = new List<string>();
for (int i = 0; i < dv.Count; i++)
{
l.Add(dv[i]["currency"].ToString());
}
Currency_List = l;
}
protected string _currency;
public string Currency
{
get
{
return _currency;
}
set
{
_currency = value;
OnPropertyChanged("Currency");
}
}
// Music Name
protected string _musicName;
public string MusicName
{
get
{
return _musicName;
}
set
{
_musicName = value;
OnPropertyChanged("MusicName");
}
}
}
这是类接口(对不起上面的格式,但不知何故我不能正确):
这是我的 DelegateCommand 类:
public class DelegateCommand : ICommand
{
private readonly Action _action;
public DelegateCommand(Action action)
{
_action = action;
}
public void Execute(object parameter)
{
_action();
}
public bool CanExecute(object parameter)
{
return true;
}
}
这是 DataTemplateSelector:
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate T1 { get; set; }
public DataTemplate T2 { get; set; }
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
string product_type = (string)item;
if (product_type == "Type1")
return T1;
else
return T2;
}
}