Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Silverlight中将字符串用作dataform的数据模板时的事件处理程序_C#_Silverlight_Xaml - Fatal编程技术网

C# 在Silverlight中将字符串用作dataform的数据模板时的事件处理程序

C# 在Silverlight中将字符串用作dataform的数据模板时的事件处理程序,c#,silverlight,xaml,C#,Silverlight,Xaml,我试图使用字符串以编程方式为数据表单形成一些xaml。我可以让组合框出现。但是当我试图使用指定字符串中“MouseLeftButtonUp”或“Loaded”事件处理程序的代码时;进入页面后,页面将变为白色(无明显错误)。请参阅下面的相关代码 StringBuilder editTemplate = new StringBuilder(""); editTemplate.Append("<DataTemplate "); editTemplate.Append

我试图使用字符串以编程方式为数据表单形成一些xaml。我可以让组合框出现。但是当我试图使用指定字符串中“MouseLeftButtonUp”或“Loaded”事件处理程序的代码时;进入页面后,页面将变为白色(无明显错误)。请参阅下面的相关代码

     StringBuilder editTemplate = new StringBuilder("");
     editTemplate.Append("<DataTemplate ");
     editTemplate.Append("xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' ");
     editTemplate.Append("xmlns:toolkit='http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit' ");
     editTemplate.Append("xmlns:navigation='clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation' ");
     editTemplate.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' >");
     editTemplate.Append("<StackPanel>");
     editTemplate.Append(@"  <toolkit:DataField Label='" + GetFieldWithoutNumber(theInfo, theDataContext) + "'>");
     /* Won't Work */ editTemplate.Append(@" <ComboBox MouseLeftButtonUp='ComboBox_MouseLeftButtonUp' />");
     /* Will Work  */ editTemplate.Append(@" <ComboBox />");
     editTemplate.Append(@" </toolkit:DataField>");
     editTemplate.Append("</StackPanel></DataTemplate>");
     dynamicDataForm.EditTemplate = XamlReader.Load(editTemplate.ToString()) as DataTemplate;
StringBuilder编辑模板=新的StringBuilder(“”);
editTemplate.Append(“”);
editTemplate.Append(“”);
editTemplate.Append(@“”);
/*无法工作*/editTemplate.Append(@“”);
/*将起作用*/editTemplate.Append(@“”);
editTemplate.Append(@“”);
editTemplate.Append(“”);
dynamicDataForm.EditTemplate=XamlReader.Load(EditTemplate.ToString())作为DataTemplate;

一种解决方案是处理数据表单的
BeginingEdit
事件,并使用该事件将事件处理程序订阅到组合框的
MouseLeftButtonUp
事件

为此,将名为
isEventWiredUp
的私有字段添加到代码后面。我们将使用此字段跟踪是否已订阅该活动,并防止该活动被订阅多次

接下来,将
x:Name=“…”
属性添加到您的
组合框中。我们使用此名称来访问组合框

完成后,添加以下两种方法,这两种方法可以满足您的需要。将
yourcomboxname
替换为您提供给组合框的
x:Name

    private void dynamicDataForm_BeginningEdit(object sender, CancelEventArgs e)
    {
        Dispatcher.BeginInvoke(OnBeginEdit);
    }

    private void OnBeginEdit()
    {
        if (!isEventWiredUp)
        {
            var combobox = dynamicDataForm.FindNameInContent("yourComboBoxName") as ComboBox;
            if (combobox != null)
            {
                combobox.MouseLeftButtonUp += combobox_MouseLeftButtonUp;
                isEventWiredUp = true;
            }
        }
    }
将这两个方法中的第一个订阅到数据表单的
beginingedit
事件

我必须承认,我无法在组合框上触发
MouseLeftButtonUp
事件。我不知道为什么会发生这种情况,但这似乎是ComboBox的一个普遍问题,而不是因为构建XAML的方式而发生的问题。但是,我能够为组合框的
SelectionChanged
事件找到一个事件处理程序


我还尝试用直接调用
OnBeginEdit
方法替换
Dispatcher.BeginInvoke
行,但我发现这种方法不起作用。这些事件没有完全正确地联系起来;同样,我也不知道为什么。

连接到XAML文件的代码隐藏中需要声明XAML中的事件处理程序。对于ResourceDictionary或从XamlReader.Load加载的任何内容,不能有任何代码隐藏,因此不能在XAML中设置事件处理程序。绕过此限制的最简单方法是,不要从字符串构建模板,只需在XAML文件的参考资料部分声明模板,然后您可以执行以下操作:

Resources[“MyTemplate”]作为数据模板

获取模板并像您在这里所做的那样在代码中分配它,或者只使用XAML中的StaticResource。只要它保持在与此代码连接的同一个XAML文件中,您当前拥有的事件处理程序就可以正常工作。字符串的动态部分也需要更改以使用绑定

如果您想坚持使用XamlReader方法,您有两个问题需要解决

  • 在渲染模板中找到ComboBox实例
  • 等待模板呈现后再查找组合框
  • 要查找组合框,首先需要在模板文本中为其指定一个x:Name属性(您可以替换当前的事件代码)。接下来,您需要能够通过名称在可视化树中定位项目。这相当简单,您可以找到一个方法来实现这一点

    要在正确的时间调用此代码,您要么需要重写OnApplyTemplate,不幸的是,如果您使用的是UserControl之类的控件,那么OnApplyTemplate将无法工作,要么使用另一个技巧在呈现所有控件之前阻止其运行。下面是一个完整的示例,可以在构造函数中使用上面链接的find方法:

    DataTemplate template = Resources["MyTemplate"] as DataTemplate;
    dynamicDataForm.ContentTemplate = template;
    
    Dispatcher.BeginInvoke(() =>
    {
        ComboBox button = FindVisualChildByName<ComboBox>(this, "MyControl");
        if (button != null)
            button.MouseLeftButtonUp += (s, _) => MessageBox.Show("Click");
    });
    
    DataTemplate=Resources[“MyTemplate”]作为DataTemplate;
    dynamicDataForm.ContentTemplate=模板;
    Dispatcher.BeginInvoke(()=>
    {
    ComboBox button=FindVisualChildByName(这是“MyControl”);
    如果(按钮!=null)
    button.MouseLeftButtonUp+=(s,)=>MessageBox.Show(“单击”);
    });
    

    在您的情况下,您的模板可能需要等待切换到编辑状态,然后才能呈现。在这种情况下,您需要暂停连接事件,并在数据表单上查找该状态更改时发生的其他事件。

    而不是尝试直接连接事件,您可以使用交互性绑定事件

    e、 g

    。。。
    editTemplate.Append(“xmlns:i='clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity'”);
    ...
    editTemplate.Append(@)
    ");
    

    您可能需要使用一些祖先绑定来访问定义处理程序的上下文。我使用InvokeCommandAction的自定义实现;基本上是System.Windows.Interactivity.InvokeCommandAction的副本,但为了将事件参数传递给命令而进行了扩展,您可能需要执行相同的操作。

    XamlReader.Load不允许在其中附加事件处理程序。 因此,请使用此技术将EventHandler动态附加到它

    1-在不使用EventHandler的情况下编写Xaml字符串-但要编写这些控件的Name属性

    2-使用
    XamlReader.Load(str)加载字符串

    3-然后从中加载DataTemplate的内容。使用
    Grid模板=((Grid)(dt.LoadContent())

    注意:
    Grid
    DataTemplate
    中的父控件

    4-按要附加事件处理程序的名称查找控件。
    Button img=(Button)template.FindName(“MyButtonInDataTemplate”)


    我希望它能有所帮助。

    这并不让我感到惊讶,您应该做的是在创建da后以编程方式连接事件处理程序
    ...
    editTemplate.Append("xmlns:i='clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity' ");
    ...
    editTemplate.Append(@"
    <ComboBox>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName='MouseLeftButtonUp'>
    
            <i:InvokeCommandAction Command='{Binding  DataContext.YourCommand,                                                                                 
               RelativeSource={RelativeSource AncestorType=XXX}}'  
               CommandParameter='{Binding}'/>
    
        </i:EventTrigger>
    </i:Interaction.Triggers>
    </ComboBox>");