【发布时间】:2014-02-27 15:57:30
【问题描述】:
我正在开发一个 LightSwitch 自定义控件,该控件能够(嗯,至少这是有意的......)根据一个可区分的值绑定和编辑各种不同的属性。
让我进一步解释一下。该表如下所示:
现在,基于Datenformat 的值,控件将自身动态绑定到ErgebnisBool、ErgebnisDatum 等,并从控件的xaml 中选择适当的DataTemplate。
ErgebnisAnzeige 是一个计算文本属性,它包含一个只读显示字符串。
控件的xaml如下:
<UserControl x:Class="EuvControlsExtension.Presentation.Controls.ProzessErgebnisEdit"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:framework ="clr-namespace:Microsoft.LightSwitch.Presentation.Framework;assembly=Microsoft.LightSwitch.Client"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
xmlns:ct="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.Input"
xmlns:multi="clr-namespace:EuvControlsExtension.Presentation.Controls"
xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"
mc:Ignorable="d"
x:Name="HostControl">
<multi:MtTemplateSelector x:Name="MyTemplateSelector"
Content="{Binding Path=RootEntity, Mode=TwoWay, ElementName=HostControl, UpdateSourceTrigger=Default}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center"
IsHitTestVisible="False">
<!--Zahl-->
<multi:MtTemplateSelector.ZahlTemplate>
<DataTemplate>
<TextBox HorizontalAlignment="Stretch"
Text="{Binding Path=RootEntity.ErgebnisZahl, ElementName=HostControl, Mode=TwoWay, UpdateSourceTrigger=Default, ValidatesOnExceptions=True, NotifyOnValidationError=True}"/>
</DataTemplate>
</multi:MtTemplateSelector.ZahlTemplate>
<!--Bool-->
<multi:MtTemplateSelector.BoolTemplate>
<DataTemplate>
<CheckBox IsThreeState="True"
Content="{Binding Path=RootEntity.ErgebnisBool, ElementName=HostControl, Mode=TwoWay, UpdateSourceTrigger=Default, ValidatesOnExceptions=True, NotifyOnValidationError=True}"/>
</DataTemplate>
</multi:MtTemplateSelector.BoolTemplate>
</multi:MtTemplateSelector>
</UserControl>
MtTemplateSelector 类只是为当前格式返回适当的 DataTemplate,这里没什么特别的。
控件本身(ProzessErgebnisEdit)也很简单。它只是绑定实体实例(称为RootEntity):
public partial class ProzessErgebnisEdit : UserControl
{
public ProzessErgebnisEdit()
{
InitializeComponent();
BindProperties();
}
private void BindProperties()
{
var binding = new Binding("DataSourceRoot.RootObject")
{
Mode = BindingMode.TwoWay
};
this.SetBinding(RootEntityProperty, binding);
}
public object RootEntity
{
get { return GetValue(RootEntityProperty); }
set { SetValue(RootEntityProperty, value); }
}
public static readonly DependencyProperty RootEntityProperty = DependencyProperty.Register(
"RootEntity",
typeof(object),
typeof(ProzessErgebnisEdit),
new PropertyMetadata(null));
}
最后一点,我有这个控件工厂,它在适当的时候返回一个只显示的 DataTemplate:
[Export(typeof(IControlFactory))]
[ControlFactory("EuvControlsExtension:ProzessErgebnisEdit")]
internal class ProzessErgebnisEditFactory : IControlFactory
{
private DataTemplate dataTemplate;
private DataTemplate displayModeDataTemplate;
public DataTemplate DataTemplate
{
get {
return this.dataTemplate ??
(this.dataTemplate = XamlReader.Load(ControlTemplate) as DataTemplate);
}
}
public DataTemplate GetDisplayModeDataTemplate(IContentItem contentItem)
{
return this.displayModeDataTemplate ??
(this.displayModeDataTemplate = XamlReader.Load(DisplayModeControlTemplate) as DataTemplate);
}
private const string DisplayModeControlTemplate =
"<DataTemplate" +
" xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" +
" <Border Background='GreenYellow'>" +
" <TextBlock Text='{Binding Path=DataSourceRoot.RootObject.ErgebnisAnzeige}' Margin='3' Foreground='Red' " +
" TextAlignment=\"{Binding Properties[Microsoft.LightSwitch:RootControl/TextAlignment]}\"" +
" VerticalAlignment=\"{Binding Properties[Microsoft.LightSwitch:RootControl/VerticalAlignment]}\" />" +
" </Border>" +
"</DataTemplate>";
private const string ControlTemplate =
"<DataTemplate" +
" xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"" +
" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"" +
" xmlns:ctl=\"clr-namespace:EuvControlsExtension.Presentation.Controls;assembly=EuvControlsExtension.Client\">" +
"<ctl:ProzessErgebnisEdit/>" +
"</DataTemplate>";
}
到目前为止一切正常:当单元格未聚焦时,仅显示文本出现(例如 Wahr/Falsch/--),当我单击编辑单元格时,它切换到适当的 DataTemplate(例如 a复选框)。并且总是显示正确的值,这告诉我数据绑定通常有效。
唯一的问题是控件始终是只读的,我无法通过代码或 xaml 或其他方式使它们可编辑。
到目前为止,我尝试拦截网格的OnPrepareCellEditing 事件,然后手动将相应列的IsReadOnly 属性设置为false,我也尝试了与控件的DataContext.IsReadOnly 属性相同的操作。运气不好...
我错过了什么?我的整个方法有缺陷吗?这里发生了什么?我无法弄清楚这种行为的原因,我什至看不到搜索的方向......
编辑:关于德语标识符 一些标识符是德语的,因此可能不是每个人都立即清楚。但最后,就这么简单:Ergebnis 是德语的Result。这个表达式经常出现在表格中,因为要显示的值是物理生产过程的结果,它可以是各种数据类型,如布尔、字符串、日期时间等(这里没什么特别的)。此信息是 Datanformat 列的内容,类似于英文的 DataType。
Edit2:模板选择器:
public class MtTemplateSelector : DataTemplateSelector
{
public DataTemplate UnknownTemplate { get; set; }
public DataTemplate ZahlTemplate { get; set; }
public DataTemplate FreitextTemplate { get; set; }
public DataTemplate AuswahlTemplate { get; set; }
public DataTemplate BoolTemplate { get; set; }
public DataTemplate DatumTemplate { get; set; }
public DataTemplate MessungTemplate { get; set; }
public DataTemplate DateiPfadTemplate { get; set; }
public DataTemplate OrdnerPfadTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
switch (GetDatenFormatEnum(item))
{
case DatenformatEnum.Zahl:
return ZahlTemplate;
...
【问题讨论】:
-
您能否尝试翻译一些德语(?),因为如果不与您共享该语言,就很难理解您的意图和含义。另外,您的问题是否同时出现在 CheckBox 和 TextBox 上?你对只读是什么意思? IsReadOnly 属性为 True,或者您的更改未对基础 ViewModel 进行?
-
所以 IsEnabled=False 是您的问题?
-
您应该在您的控件中调试并检查 IsEnabledCore 的值。您尝试做的事情是使用 CustomControl 而不是 UserControl 更好地完成,这是制作新的和可重用控件的方式。您可能也应该共享 MtTemplateSelector 类,为什么要设置 IsHitTestVisible=False?
-
@Zache IsEnabled/IsEnabledCore 都是“真”——我已经调试过了。关于其他事情:我继承了几乎所有这些代码,我不想在不知道发生了什么的情况下更改它。我在问题中添加了 MtTemplateSelector 类,但正如我所说,它非常简单,我很确定它没有参与问题。
-
那么控件不是“灰显”的吗?那么 IsHitTestEnalbed=False 应该是您的问题,它会阻止控件(及其子控件)接收用户输入。
标签: c# xaml visual-studio-lightswitch