Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.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/4/wpf/14.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中的值适配到不可绑定属性_C#_Wpf_Xaml_Mvvm - Fatal编程技术网

C# 如何将xaml中的值适配到不可绑定属性

C# 如何将xaml中的值适配到不可绑定属性,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,如何将以下代码编写为XAML 假设我们有这段代码 var myValue = someMethodeReturn(); // the return will fit // could also be an other nonbindable property var myTextBlock = new TextBlock(); myTextBlock.Inlines = myValue; 你将如何转换 var my

如何将以下代码编写为XAML

假设我们有这段代码

        var myValue = someMethodeReturn(); // the return will fit

        // could also be an other nonbindable property
        var myTextBlock = new TextBlock();
        myTextBlock.Inlines = myValue;
你将如何转换

       var myValue = someMethodeReturn(); 

仅作为XAML

当然,第一部分可能看起来像
?={Binding myProperty}

以及类似于
的secound部分,以添加您可以使用的字符串值

myTextBlock.Inlines.Add(new Run(myValue));
如果myValue是数组,则循环并添加多个运行元素


运行类的Msdn文档我的想法是使用ItemsControl并将ItemPanel设置为WrapPanel,然后为每个项目插入文本块或ContentPresenter。事实证明,这些文本块不会像我预期的那样包装得很好:

好吧,您至少有一个ViewModel,那么在将文本项提交到源集合之前,如何将它们通过绞肉机?然后再看:

现在,如果它也能感觉到正确的话!也许你至少可以用一点

视图模型:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private ObservableCollection<MyRunModel> _myRuns = new ObservableCollection<MyRunModel>();
    public ObservableCollection<MyRunModel> MyRuns { get { return _myRuns; } set { _myRuns = value; OnPropertyChanged("MyRuns"); } }


    public ViewModel()
    {
        List<MyRunModel> runs = new List<MyRunModel>();
        runs.Add(new MyRunModel() { Text = "Meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr lange run1" });
        runs.Add(new MyRunModel() { Text = "Meine run2", Foreground = ForegroundDescription.HighlightDark });
        runs.Add(new MyRunModel() { Text = "Meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr lange run3" });
        runs.Add(new MyRunModel() { Text = "Meine run4", Foreground = ForegroundDescription.HighlightLight, Background = BackgroundDescription.Highlight });
        runs.Add(new MyRunModel() { Text = "Meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr lange run5" });

        CommitMyRuns(runs);
    }

    /// <summary>
    /// Splits up every run into words (delimited by space), and adds the parts 
    /// to the collection that can be bound to the UI. Retains formatting information.
    /// </summary>
    /// <param name="runs"></param>
    private void CommitMyRuns(List<MyRunModel> runs)
    {
        int runCount = runs.Count;
        for (int i = 0; i < runCount; i++)
        {
            string[] parts = runs[i].Text.Split(' ');
            int partCount = parts.Length;
            for (int j = 0; j < partCount; j++)
            {
                bool isLast = j == parts.Length - 1;
                MyRunModel run = new MyRunModel()
                {
                    Text = parts[j] + (isLast ? string.Empty : " "),  // add space that was lost in split
                    Foreground = runs[i].Foreground, // keep formatting
                    Background = runs[i].Background
                };
                MyRuns.Add(run);
            }
            MyRuns.Add(new MyRunModel() { Text = " " }); // add a space after each of the original runs (unformatted)
        }
    }

}
public class MyRunModel
{
    public string Text { get; set; }
    // do not use UI types (e.g. Brush) directly in viewmodel
    public ForegroundDescription Foreground { get; set; }
    public BackgroundDescription Background { get; set; }
}

public enum ForegroundDescription
{
    None = 0,
    HighlightDark,
    HighlightLight
}

public enum BackgroundDescription
{
    None = 0,
    Highlight
}
公共类视图模型:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
私有void OnPropertyChanged(字符串propertyName)
{
if(this.PropertyChanged!=null)
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
私有ObservableCollection _myRuns=新ObservableCollection();
公共ObservableCollection MyRuns{get{return{uMyRuns;}set{{uMyRuns=value;OnPropertyChanged(“MyRuns”);}
公共视图模型()
{
列表运行=新建列表();
添加(新的MyRunModel(){Text=“Meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr lange run1”});
添加(新的MyRunModel(){Text=“Meine run2”,前台=ForegroundDescription.HighlightDark});
添加(新的MyRunModel(){Text=“Meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr lange run3”});
添加(新的MyRunModel(){Text=“Meine run4”,前台=ForegroundDescription.Highlight,后台=BackgroundDescription.Highlight});
添加(新的MyRunModel(){Text=“Meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr lange run5”});
委员会(运行);
}
/// 
///将每次运行拆分为单词(由空格分隔),并添加部分
///指向可绑定到UI的集合。保留格式信息。
/// 
/// 
私人作废佣金(列表运行)
{
int runCount=runs.Count;
对于(int i=0;i
Xaml:



子类化文本框以使内联线可绑定可能是一种可能性。请参见。

创建可绑定的
内联线
附加属性,如下所示:

Bindable.cs

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace WpfApplication
{
    public static class Bindable
    {
        public static readonly DependencyProperty InlinesProperty = DependencyProperty.RegisterAttached("Inlines", typeof(IEnumerable<Inline>), typeof(Bindable), new PropertyMetadata(OnInlinesChanged));

        private static void OnInlinesChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            var textBlock = source as TextBlock;

            if (textBlock != null)
            {
                textBlock.Inlines.Clear();
                var inlines = e.NewValue as IEnumerable<Inline>;
                if (inlines != null)
                    textBlock.Inlines.AddRange(inlines);
            }
        }

        [AttachedPropertyBrowsableForType(typeof(TextBlock))]
        public static IEnumerable<Inline> GetInlines(this TextBlock textBlock)
        {
            return (IEnumerable<Inline>)textBlock.GetValue(InlinesProperty);
        }

        public static void SetInlines(this TextBlock textBlock, IEnumerable<Inline> inlines)
        {
            textBlock.SetValue(InlinesProperty, inlines);
        }
    }
}
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfApplication
{
    public class MyViewModel
    {
        // This is against MVVM principle - to contain views (Inlines) in view model, but I don't want to complicate by creating ViewModel class for each Inline derived class.
        public IEnumerable<Inline> Inlines { get; private set; }

        public MyViewModel()
        {
            this.Inlines = new Inline[]
            {
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run 1"),
                new Run("meine run2") { Foreground = Brushes.Green, Typography = { Variants = FontVariants.Superscript } },
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run"),
                new Run("meine run3") { Foreground = Brushes.LimeGreen, Background = Brushes.Yellow },
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run")
            };
        }
    }
}
使用System.Collections.Generic;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Documents;
命名空间WpfApplication
{
公共静态类可绑定
{
public static readonly dependencProperty InlinesProperty=dependencProperty.RegisterAttached(“Inlines”、typeof(IEnumerable)、typeof(Bindable)、new PropertyMetadata(OnInlinesChanged));
InLinesChanged上的私有静态无效(DependencyObject源,DependencyPropertyChangedEventArgs e)
{
var textBlock=源作为textBlock;
if(textBlock!=null)
{
textBlock.Inlines.Clear();
var inlines=e.NewValue作为IEnumerable;
如果(内联线!=null)
textBlock.Inlines.AddRange(Inlines);
}
}
[AttachedPropertyBrowsableForType(typeof(TextBlock))]
公共静态IEnumerable GetInlines(此TextBlock TextBlock)
{
return(IEnumerable)textBlock.GetValue(InlinesProperty);
}
公共静态void SetInlines(此TextBlock TextBlock,IEnumerable inlines)
{
设置值(InlinesProperty,inlines);
}
}
}
然后像这样使用它:

MyViewModel.cs

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace WpfApplication
{
    public static class Bindable
    {
        public static readonly DependencyProperty InlinesProperty = DependencyProperty.RegisterAttached("Inlines", typeof(IEnumerable<Inline>), typeof(Bindable), new PropertyMetadata(OnInlinesChanged));

        private static void OnInlinesChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            var textBlock = source as TextBlock;

            if (textBlock != null)
            {
                textBlock.Inlines.Clear();
                var inlines = e.NewValue as IEnumerable<Inline>;
                if (inlines != null)
                    textBlock.Inlines.AddRange(inlines);
            }
        }

        [AttachedPropertyBrowsableForType(typeof(TextBlock))]
        public static IEnumerable<Inline> GetInlines(this TextBlock textBlock)
        {
            return (IEnumerable<Inline>)textBlock.GetValue(InlinesProperty);
        }

        public static void SetInlines(this TextBlock textBlock, IEnumerable<Inline> inlines)
        {
            textBlock.SetValue(InlinesProperty, inlines);
        }
    }
}
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfApplication
{
    public class MyViewModel
    {
        // This is against MVVM principle - to contain views (Inlines) in view model, but I don't want to complicate by creating ViewModel class for each Inline derived class.
        public IEnumerable<Inline> Inlines { get; private set; }

        public MyViewModel()
        {
            this.Inlines = new Inline[]
            {
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run 1"),
                new Run("meine run2") { Foreground = Brushes.Green, Typography = { Variants = FontVariants.Superscript } },
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run"),
                new Run("meine run3") { Foreground = Brushes.LimeGreen, Background = Brushes.Yellow },
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run")
            };
        }
    }
}
使用System.Collections.Generic;
使用System.Windows;
使用System.Windows.Documents;
使用System.Windows.Media;
命名空间WpfApplication
{
公共类MyViewModel
{
<Window.DataContext>
    <local:ViewModel />
</Window.DataContext>

<Window.Resources>
    <SolidColorBrush x:Key="ForegroundHighlightDarkBrush" Color="Green" />
    <SolidColorBrush x:Key="ForegroundHighlightLightBrush" Color="LimeGreen" />
    <SolidColorBrush x:Key="BackgroundHighlightBrush" Color="Yellow" />
</Window.Resources>

<Grid>
    <TextBlock>
        <TextBlock.Inlines>
            <ItemsControl ItemsSource="{Binding MyRuns}" HorizontalContentAlignment="Stretch">
                <ItemsControl.ItemTemplate>
                    <DataTemplate DataType="{x:Type local:MyRunModel}">
                        <TextBlock x:Name="presenter" TextWrapping="Wrap" Text="{Binding Text}"/>
                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding Foreground}" Value="HighlightDark">
                                <Setter TargetName="presenter" Property="TextElement.Foreground" Value="{StaticResource ForegroundHighlightDarkBrush}" />
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Foreground}" Value="HighlightLight">
                                <Setter TargetName="presenter" Property="TextElement.Foreground" Value="{StaticResource ForegroundHighlightLightBrush}" />
                            </DataTrigger>
                            <DataTrigger Binding="{Binding Background}" Value="Highlight">
                                <Setter TargetName="presenter" Property="TextElement.Background" Value="{StaticResource BackgroundHighlightBrush}" />
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel Orientation="Horizontal" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </TextBlock.Inlines>
    </TextBlock>
</Grid>
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

namespace WpfApplication
{
    public static class Bindable
    {
        public static readonly DependencyProperty InlinesProperty = DependencyProperty.RegisterAttached("Inlines", typeof(IEnumerable<Inline>), typeof(Bindable), new PropertyMetadata(OnInlinesChanged));

        private static void OnInlinesChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
        {
            var textBlock = source as TextBlock;

            if (textBlock != null)
            {
                textBlock.Inlines.Clear();
                var inlines = e.NewValue as IEnumerable<Inline>;
                if (inlines != null)
                    textBlock.Inlines.AddRange(inlines);
            }
        }

        [AttachedPropertyBrowsableForType(typeof(TextBlock))]
        public static IEnumerable<Inline> GetInlines(this TextBlock textBlock)
        {
            return (IEnumerable<Inline>)textBlock.GetValue(InlinesProperty);
        }

        public static void SetInlines(this TextBlock textBlock, IEnumerable<Inline> inlines)
        {
            textBlock.SetValue(InlinesProperty, inlines);
        }
    }
}
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfApplication
{
    public class MyViewModel
    {
        // This is against MVVM principle - to contain views (Inlines) in view model, but I don't want to complicate by creating ViewModel class for each Inline derived class.
        public IEnumerable<Inline> Inlines { get; private set; }

        public MyViewModel()
        {
            this.Inlines = new Inline[]
            {
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run 1"),
                new Run("meine run2") { Foreground = Brushes.Green, Typography = { Variants = FontVariants.Superscript } },
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run"),
                new Run("meine run3") { Foreground = Brushes.LimeGreen, Background = Brushes.Yellow },
                new Run("meine sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr sehr  lange run")
            };
        }
    }
}
<Window x:Class="WpfApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication">
    <Window.DataContext>
        <local:MyViewModel/>
    </Window.DataContext>
    <TextBlock local:Bindable.Inlines="{Binding Inlines}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="LightGray" TextWrapping="WrapWithOverflow"/>
</Window>