Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.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/6/asp.net-mvc-3/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# 如何从XAML中定义的ControlTemplate访问元素(图像)_C#_Wpf_Xaml_Templates - Fatal编程技术网

C# 如何从XAML中定义的ControlTemplate访问元素(图像)

C# 如何从XAML中定义的ControlTemplate访问元素(图像),c#,wpf,xaml,templates,C#,Wpf,Xaml,Templates,1) 将以下代码复制并粘贴到MainWindow.xaml文件中 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Widt

1) 将以下代码复制并粘贴到MainWindow.xaml文件中

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Window.Resources>
    <Style x:Key="ContextMenuStyle" TargetType="{x:Type ContextMenu}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <Border Background="MediumPurple" BorderThickness="1" BorderBrush="MediumPurple" CornerRadius="5">
                        <StackPanel>
                            <Button Margin="3,3,3,3" Height="26" Command="ApplicationCommands.Cut">
                                <DockPanel HorizontalAlignment="Left" Width="150">
                                    <Image x:Name="Image1" Height="20" Width="30"/>
                                    <TextBlock Margin="5,2,5,0" FontSize="16" FontWeight="Bold" FontFamily="Wingdings 2" Text="&amp;"/>
                                    <TextBlock VerticalAlignment="Center" FontWeight="Bold" Text="Cut"/>
                                    <TextBlock VerticalAlignment="Center" TextAlignment="Right" Margin="0,0,5,0" Text="Ctrl+X"/>
                                </DockPanel>
                            </Button>
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    </Window.Resources>
    <Grid>
        <TextBox Height="50" Width="300">
            <TextBox.ContextMenu>
                <ContextMenu Style="{StaticResource ContextMenuStyle}"/>
            </TextBox.ContextMenu>
        </TextBox>
    </Grid>
</Window>
  • 这是错误消息:
  • 名称“Image1”在当前上下文中不存在

  • 这是错误图片:
  • 那么,如何从xaml控制模板访问Image1元素呢?

    模板(ControlTemplate、DataTemplate)预计将用于创建同一布局的多个副本。这些副本可以通过绑定或资源进行参数化

    要设置模板内图像的源,可以使用

    1) 动力源

    xaml中的更改:

    <Image x:Name="Image1" Height="20" Width="30" Source="{DynamicResource MyPicture}"/>
    
    <Image x:Name="Image1" Height="20" Width="30" Source="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
    
    2) 装订

    xaml中的更改:

    <Image x:Name="Image1" Height="20" Width="30" Source="{DynamicResource MyPicture}"/>
    
    <Image x:Name="Image1" Height="20" Width="30" Source="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
    
    使用Tag是一个快速而肮脏的解决方案。当我需要自定义模板时,我更喜欢创建专门的附加依赖属性-有关详细信息,请参阅。模板(ControlTemplate、DataTemplate)预期用于创建同一布局的多个副本。这些副本可以通过绑定或资源进行参数化

    要设置模板内图像的源,可以使用

    1) 动力源

    xaml中的更改:

    <Image x:Name="Image1" Height="20" Width="30" Source="{DynamicResource MyPicture}"/>
    
    <Image x:Name="Image1" Height="20" Width="30" Source="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
    
    2) 装订

    xaml中的更改:

    <Image x:Name="Image1" Height="20" Width="30" Source="{DynamicResource MyPicture}"/>
    
    <Image x:Name="Image1" Height="20" Width="30" Source="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType=ContextMenu}}"/>
    
    使用Tag是一个快速而肮脏的解决方案。当我需要自定义模板时,我更喜欢创建专门的附加依赖属性-有关详细信息,请参阅。如果真正的问题是“如何设置Image.Source from base64 string”,则可以使用值转换器,而无需代码隐藏:

    转换器:

    public class Base64ImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string)
            {
                return BitmapFrame.Create(new System.IO.MemoryStream(System.Convert.FromBase64String((string)value)), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            }
    
            return null;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
    模板:

    <Window.Resources>
        <local:Base64ImageConverter x:Key="imageConverter"/>
    
        <system:String x:Key="imageLetter">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</system:String>
    
        <Style x:Key="ContextMenuStyle" TargetType="{x:Type ContextMenu}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ContextMenu}">
                        <Border Background="MediumPurple" BorderThickness="1" BorderBrush="MediumPurple" CornerRadius="5">
                            <StackPanel>
                                <Button Margin="3,3,3,3" Height="26" Command="ApplicationCommands.Cut">
                                    <DockPanel HorizontalAlignment="Left" Width="150">
                                        <Image x:Name="Image1" Height="20" Width="30" Source="{Binding Source={StaticResource imageLetter}, Converter={StaticResource imageConverter}}"/>
                                        <TextBlock Margin="5,2,5,0" FontSize="16" FontWeight="Bold" FontFamily="Wingdings 2" Text="&amp;"/>
                                        <TextBlock VerticalAlignment="Center" FontWeight="Bold" Text="Cut"/>
                                        <TextBlock VerticalAlignment="Center" TextAlignment="Right" Margin="0,0,5,0" Text="Ctrl+X"/>
                                    </DockPanel>
                                </Button>
                            </StackPanel>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    
    如果真正的问题是“如何从base64字符串设置Image.Source”,则可以使用值转换器,而无需代码隐藏:

    转换器:

    public class Base64ImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is string)
            {
                return BitmapFrame.Create(new System.IO.MemoryStream(System.Convert.FromBase64String((string)value)), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            }
    
            return null;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
    模板:

    <Window.Resources>
        <local:Base64ImageConverter x:Key="imageConverter"/>
    
        <system:String x:Key="imageLetter">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</system:String>
    
        <Style x:Key="ContextMenuStyle" TargetType="{x:Type ContextMenu}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ContextMenu}">
                        <Border Background="MediumPurple" BorderThickness="1" BorderBrush="MediumPurple" CornerRadius="5">
                            <StackPanel>
                                <Button Margin="3,3,3,3" Height="26" Command="ApplicationCommands.Cut">
                                    <DockPanel HorizontalAlignment="Left" Width="150">
                                        <Image x:Name="Image1" Height="20" Width="30" Source="{Binding Source={StaticResource imageLetter}, Converter={StaticResource imageConverter}}"/>
                                        <TextBlock Margin="5,2,5,0" FontSize="16" FontWeight="Bold" FontFamily="Wingdings 2" Text="&amp;"/>
                                        <TextBlock VerticalAlignment="Center" FontWeight="Bold" Text="Cut"/>
                                        <TextBlock VerticalAlignment="Center" TextAlignment="Right" Margin="0,0,5,0" Text="Ctrl+X"/>
                                    </DockPanel>
                                </Button>
                            </StackPanel>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    

    您希望这种方法如何处理多个这样的ContextMenu?通常避免从代码中访问UI元素。相反,将图像的源属性绑定到视图模型属性,即视图的DataContext中对象的属性。开始阅读此处:,并在web上搜索“wpf mvvm”。@Clemens,该问题可能不需要mvvm,因为它只是自定义视图,在视图中执行了哪些操作?您希望这种方法如何处理多个这样的ContextMenu?通常避免从代码中访问UI元素。相反,将映像的源属性绑定到视图模型属性,即视图的DataContext中对象的属性。开始阅读此处:,并在web上搜索“wpf mvvm”。@Clemens,该问题可能不需要mvvm,因为它只是在视图中完成的视图自定义