কীভাবে ডাব্লুপিএফ-তে একাধিক শৈলী প্রয়োগ করা যায়


153

ডাব্লুপিএফ-এ, আমি কীভাবে একাধিক শৈলী প্রয়োগ করব FrameworkElement? উদাহরণস্বরূপ, আমার একটি কন্ট্রোল রয়েছে যার ইতিমধ্যে একটি স্টাইল রয়েছে। আমার একটি পৃথক শৈলীও রয়েছে যা আমি এটির সাথে প্রথমটি না ফেলেই যুক্ত করতে চাই। শৈলীর বিভিন্ন টার্গেটটাইপ রয়েছে, তাই আমি কেবল অন্যটির সাথে প্রসারিত করতে পারি না।


ওপি কখনই তার নির্দিষ্ট শৈলীর একক নিয়ন্ত্রণের জন্য অনন্য কিনা তা নির্দিষ্ট করে না। এই পৃষ্ঠায় দেওয়া উত্তরগুলি একাধিক নিয়ন্ত্রণের মাধ্যমে উভয় শৈলীর ভাগ করে নেওয়ার প্রয়োজনীয়তা ধরে নেয়। : আপনি নিয়ন্ত্রণ ব্যবহারের বেস শৈলী একটি উপায় খুঁজছেন এবং স্বতন্ত্র বৈশিষ্ট্য পৃথক নিয়ন্ত্রণ সরাসরি ওভাররাইড থাকেন: এই উত্তর দেখার stackoverflow.com/a/54497665/1402498
JamesHoux

উত্তর:


154

আমি মনে করি এর সহজ উত্তরটি হ'ল আপনি যা করতে চাইছেন (কমপক্ষে ডাব্লুপিএফের এই সংস্করণে) আপনি পারবেন না।

অর্থাৎ যে কোনও নির্দিষ্ট উপাদানের জন্য কেবল একটি স্টাইল প্রয়োগ করা যেতে পারে।

তবে অন্যরা যেমন উপরে বলেছে, সম্ভবত আপনি BasedOnআপনাকে সাহায্য করতে পারেন to আলগা জ্যামালের নীচের অংশটি দেখুন। এটিতে আপনি দেখতে পাবেন যে আমার কাছে একটি বেস শৈলী রয়েছে যা এমন একটি সম্পত্তি সেট করে যা আমি উপাদানটির বেস বর্গের উপর বিদ্যমান যা আমি দুটি স্টাইল প্রয়োগ করতে চাই। এবং, দ্বিতীয় শৈলীতে যা বেস শৈলীর উপর ভিত্তি করে, আমি অন্য সম্পত্তি সেট করেছিলাম।

সুতরাং, এখানে ধারণাটি ... আপনি যদি সেট করতে চান এমন বৈশিষ্ট্যগুলি কোনওভাবে আলাদা করতে পারেন ... আপনি যে উপাদানটি একাধিক শৈলী সেট করতে চান তার উত্তরাধিকারের শ্রেণিবিন্যাস অনুসারে ... আপনার কার্যকারিতা থাকতে পারে।

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <Style x:Key="baseStyle" TargetType="FrameworkElement">
            <Setter Property="HorizontalAlignment" Value="Left"/>
        </Style>
        <Style TargetType="Button" BasedOn="{StaticResource baseStyle}">
            <Setter Property="Content" Value="Hello World"/>
        </Style>
    </Page.Resources>
    <Grid>
        <Button Width="200" Height="50"/>
    </Grid>
</Page>


আশাকরি এটা সাহায্য করবে.

বিঃদ্রঃ:

বিশেষভাবে একটি বিষয় লক্ষণীয়। আপনি যদি TargetTypeদ্বিতীয় স্টাইলে (উপরের এক্সএএমএল এর প্রথম সেটটিতে) পরিবর্তন করেন ButtonBaseতবে দুটি স্টাইল প্রয়োগ হয় না। তবে সেই সীমাবদ্ধতাটি পেতে নীচের নীচের এক্সএএমএলটি দেখুন। মূলত, এর অর্থ হল আপনার স্টাইলটিকে একটি কী দেওয়া উচিত এবং সেই কীটির সাথে এটি উল্লেখ করা উচিত।

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <Style x:Key="baseStyle" TargetType="FrameworkElement">
            <Setter Property="HorizontalAlignment" Value="Left"/>
        </Style>
        <Style x:Key="derivedStyle" TargetType="ButtonBase" BasedOn="{StaticResource baseStyle}">
            <Setter Property="Content" Value="Hello World"/>
        </Style>
    </Page.Resources>
    <Grid>
        <Button Width="200" Height="50" Style="{StaticResource derivedStyle}"/>
    </Grid>
</Page>

10
মনে রাখবেন ... ** অর্ডার করা গুরুত্বপূর্ণ **। derivedStyleপরে আসা আবশ্যকbaseStyle
MSFT - SliverNinja

50

"ডাব্লুপিএফ-এ আমি কীভাবে একাধিক শৈলী সেট করতে পারি?" শিরোনামে বি স্টলনিটসের একটি মার্কআপ এক্সটেনশন ব্যবহার সম্পর্কে একটি ভাল ব্লগ পোস্ট ছিল ?

সেই ব্লগটি এখন মারা গেছে, তাই আমি এখানে পোস্টটি পুনরায় প্রজনন করছি


ডাব্লুপিএফ এবং সিলভারলাইট উভয়ই "বেসডন" সম্পত্তির মাধ্যমে অন্য স্টাইলের থেকে একটি স্টাইল প্রাপ্ত করার ক্ষমতা সরবরাহ করে। এই বৈশিষ্ট্যটি বিকাশকারীদের বর্গ উত্তরাধিকারের মতো একই শ্রেণিবিন্যাস ব্যবহার করে তাদের স্টাইলগুলি সংগঠিত করতে সক্ষম করে। নিম্নলিখিত শৈলী বিবেচনা করুন:

<Style TargetType="Button" x:Key="BaseButtonStyle">
    <Setter Property="Margin" Value="10" />
</Style>
<Style TargetType="Button" x:Key="RedButtonStyle" BasedOn="{StaticResource BaseButtonStyle}">
    <Setter Property="Foreground" Value="Red" />
</Style>

এই সিনট্যাক্সের সাহায্যে, একটি বোতাম যা রেডবটনস্টাইল ব্যবহার করে তার ফোরগ্রাউন্ড সম্পত্তি রেডে সেট করবে এবং এর মার্জিন সম্পত্তিটি 10 ​​এ সেট থাকবে।

এই বৈশিষ্ট্যটি দীর্ঘকাল ধরে ডাব্লুপিএফ-এ রয়েছে এবং সিলভারলাইট 3 এ এটি নতুন।

আপনি যদি কোনও উপাদানটিতে একাধিক স্টাইল সেট করতে চান তবে কী হবে? ডাব্লুপিএফ বা সিলভারলাইট উভয়ই বাক্সের বাইরে এই সমস্যার সমাধান করতে পারে না। ভাগ্যক্রমে ডাব্লুপিএফ এ আচরণ বাস্তবায়নের উপায় আছে যা আমি এই ব্লগ পোস্টে আলোচনা করব discuss

ডাব্লুপিএফ এবং সিলভারলাইট মানগুলি সরবরাহের জন্য মার্কআপ এক্সটেনশানগুলি ব্যবহার করে যার জন্য কিছু যুক্তির প্রয়োজন। এক্সএএমএলে তাদের চারপাশে কোঁকড়ানো বন্ধনী উপস্থিতি দ্বারা মার্কআপ এক্সটেনশনগুলি সহজেই সনাক্তযোগ্য recogn উদাহরণস্বরূপ, {বাইন্ডিং} মার্কআপ এক্সটেনশনে কোনও ডেটা উত্স থেকে কোনও মূল্য আনতে এবং পরিবর্তনগুলি ঘটে যখন তা আপডেট করার জন্য যুক্তিযুক্ত থাকে; {স্ট্যাটিক রিসোর্স} মার্কআপ এক্সটেনশনে একটি কী এর উপর ভিত্তি করে রিসোর্স ডিকশনারি থেকে একটি মান ধরার জন্য যুক্তি রয়েছে। সৌভাগ্যক্রমে আমাদের জন্য, ডাব্লুপিএফ ব্যবহারকারীদের নিজস্ব কাস্টম মার্কআপ এক্সটেনশন লিখতে দেয় write এই বৈশিষ্ট্যটি এখনও সিলভারলাইটে উপস্থিত নেই, সুতরাং এই ব্লগে সমাধানটি কেবল ডাব্লুপিএফের জন্য প্রযোজ্য।

অন্যরা মার্কআপ এক্সটেনশানগুলি ব্যবহার করে দুটি স্টাইলকে একত্রিত করার দুর্দান্ত সমাধান লিখেছেন। যাইহোক, আমি এমন একটি সমাধান চেয়েছিলাম যা সীমাহীন সংখ্যক শৈলীর একত্রীকরণের ক্ষমতা সরবরাহ করেছিল যা কিছুটা জটিল।

মার্কআপ এক্সটেনশন লেখা সহজবোধ্য। প্রথম পদক্ষেপটি এমন একটি ক্লাস তৈরি করা যা মার্কআপএক্সটেনশন থেকে উদ্ভূত হয় এবং মার্কআপএক্সটেনশান রিটারনটাইপ বৈশিষ্ট্যটি ব্যবহার করে এটি নির্দেশ করে যে আপনি নিজের মার্কআপ এক্সটেনশান থেকে প্রত্যাবর্তিত মানটি টাইপের ধরণের হতে চান।

[MarkupExtensionReturnType(typeof(Style))]
public class MultiStyleExtension : MarkupExtension
{
}

মার্কআপ এক্সটেনশনে ইনপুট নির্দিষ্ট করে

আমরা আমাদের মার্কআপ এক্সটেনশনের ব্যবহারকারীদের শৈলগুলি মার্জ করার জন্য নির্দিষ্ট করার একটি সহজ উপায় দিতে চাই। মূলত দুটি উপায় রয়েছে যার মাধ্যমে ব্যবহারকারী একটি চিহ্নআপ এক্সটেনশনের ইনপুট নির্দিষ্ট করতে পারে। ব্যবহারকারীর বৈশিষ্ট্য নির্ধারণ করতে বা নির্মাণকারীর কাছে পরামিতিগুলি পাস করতে পারেন। যেহেতু এই দৃশ্যে ব্যবহারকারীর সীমাহীন সংখ্যক শৈলী নির্দিষ্টকরণের দক্ষতার প্রয়োজন হয়, তাই আমার প্রথম পদ্ধতিটি ছিল এমন একটি কনস্ট্রাক্টর তৈরি করা যা "প্যারাম" কীওয়ার্ডটি ব্যবহার করে যে কোনও সংখ্যক স্ট্রিং নেয়:

public MultiStyleExtension(params string[] inputResourceKeys)
{
}

আমার লক্ষ্যটি ছিল ইনপুটগুলি নিম্নরূপে লিখতে পারা:

<Button Style="{local:MultiStyle BigButtonStyle, GreenButtonStyle}"  />

বিভিন্ন স্টাইল কীগুলি আলাদা করে কমাটি দেখুন। দুর্ভাগ্যক্রমে, কাস্টম মার্কআপ এক্সটেনশানগুলি সীমাহীন সংখ্যক কনস্ট্রাক্টর প্যারামিটার সমর্থন করে না, সুতরাং এই পদ্ধতির ফলে একটি সংকলন ত্রুটির ফলস্বরূপ। আমি যদি জানতাম যে আমি কয়টি শৈলীর একত্রীকরণ করতে চাইছিলাম তবে আমি কনস্ট্রাক্টরের পছন্দসই সংখ্যক স্ট্রিং গ্রহণ করে একই এক্সএএমএল সিনট্যাক্সটি ব্যবহার করতে পারতাম:

public MultiStyleExtension(string inputResourceKey1, string inputResourceKey2)
{
}

কার্যকারণ হিসাবে, আমি সিদ্ধান্ত নিয়েছি যে কনস্ট্রাক্টর পরামিতিটি একটি একক স্ট্রিং নেবে যা শৈলীর নামগুলি ফাঁক দিয়ে পৃথক করে। বাক্য গঠন খুব খারাপ নয়:

private string[] resourceKeys;

public MultiStyleExtension(string inputResourceKeys)
{
    if (inputResourceKeys == null)
    {
        throw new ArgumentNullException("inputResourceKeys");
    }

    this.resourceKeys = inputResourceKeys.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

    if (this.resourceKeys.Length == 0)
    {
        throw new ArgumentException("No input resource keys specified.");
    }
}

মার্কআপ এক্সটেনশনের আউটপুট গণনা করা হচ্ছে

মার্কআপ এক্সটেনশনের আউটপুট গণনা করতে, আমাদের "প্রোভাইডভ্যালু" নামক মার্কআপএক্সটেনশন থেকে একটি পদ্ধতি ওভাররাইড করতে হবে। এই পদ্ধতি থেকে প্রত্যাবর্তিত মানটি মার্কআপ এক্সটেনশনের লক্ষ্যে সেট করা হবে।

আমি স্টাইলের জন্য একটি এক্সটেনশন পদ্ধতি তৈরি করে শুরু করেছি যা কীভাবে দুটি শৈলীর একত্রীকরণ করতে জানে। এই পদ্ধতির কোডটি বেশ সহজ:

public static void Merge(this Style style1, Style style2)
{
    if (style1 == null)
    {
        throw new ArgumentNullException("style1");
    }
    if (style2 == null)
    {
        throw new ArgumentNullException("style2");
    }

    if (style1.TargetType.IsAssignableFrom(style2.TargetType))
    {
        style1.TargetType = style2.TargetType;
    }

    if (style2.BasedOn != null)
    {
        Merge(style1, style2.BasedOn);
    }

    foreach (SetterBase currentSetter in style2.Setters)
    {
        style1.Setters.Add(currentSetter);
    }

    foreach (TriggerBase currentTrigger in style2.Triggers)
    {
        style1.Triggers.Add(currentTrigger);
    }

    // This code is only needed when using DynamicResources.
    foreach (object key in style2.Resources.Keys)
    {
        style1.Resources[key] = style2.Resources[key];
    }
}

উপরের যুক্তি দিয়ে, দ্বিতীয় শৈলীতে সমস্ত তথ্য অন্তর্ভুক্ত করতে প্রথম স্টাইলটি সংশোধন করা হয়েছে। যদি দ্বন্দ্ব হয় (যেমন উভয় শৈলীর একই সম্পত্তির জন্য একটি সেটর রয়েছে), দ্বিতীয় শৈলীতে জয়ী হয়। লক্ষ্য করুন যে শৈলী এবং ট্রিগারগুলি অনুলিপি করা বাদ দিয়ে আমি দ্বিতীয় লক্ষ্য অনুসারে টার্গেটটাইপ এবং বেসডন মানগুলিও গ্রহণ করেছি any মার্জ করা শৈলীর টার্গেটটাইপের জন্য, আমি যে কোনও প্রকারের ব্যবহার আরও বেশি প্রাপ্ত। যদি দ্বিতীয় শৈলীর ভিত্তিভিত্তিক শৈলী থাকে তবে আমি এর শৈলীর স্তরক্রমকে পুনরাবৃত্তভাবে মার্জ করি। যদি এর সংস্থান থাকে তবে আমি এগুলি প্রথম স্টাইলে অনুলিপি করব। যদি সেই সংস্থানগুলি {স্ট্যাটিক রিসোর্স using ব্যবহার করে উল্লেখ করা হয়, তবে এই মার্জ কোডটি কার্যকর করার আগে এগুলি স্থিতিশীলভাবে সমাধান করা হয়েছে, এবং সেজন্য এগুলি সরানোর প্রয়োজন হয় না। আমরা এই কোডটি যুক্ত করেছিলাম যদি আমরা ডায়নামিক রিসোর্স ব্যবহার করি।

উপরে প্রদর্শিত এক্সটেনশন পদ্ধতিটি নিম্নলিখিত সিনট্যাক্সটিকে সক্ষম করে:

style1.Merge(style2);

ProvideValue এর মধ্যে আমার উভয় শৈলীর উদাহরণ রয়েছে এই সংশ্লেষটি কার্যকর। ভাল, আমি না। কনস্ট্রাক্টরের কাছ থেকে আমি যা পেয়েছি তা হ'ল স্টাইলগুলির স্ট্রিং কীগুলির একটি তালিকা। কনস্ট্রাক্টর প্যারামিটারগুলিতে যদি প্যারামগুলির জন্য সমর্থন থাকত তবে আমি প্রকৃত শৈলীর উদাহরণগুলি পেতে নিম্নলিখিত সিনট্যাক্সটি ব্যবহার করতে পারতাম:

<Button Style="{local:MultiStyle {StaticResource BigButtonStyle}, {StaticResource GreenButtonStyle}}"/>
public MultiStyleExtension(params Style[] styles)
{
}

কিন্তু এটি কাজ করে না। এমনকি যদি প্যারামগুলির সীমাবদ্ধতা না উপস্থিত থাকে তবে আমরা সম্ভবত মার্কআপ এক্সটেনশনের আরও একটি সীমাবদ্ধতা আঘাত করব, যেখানে স্থির সংস্থানগুলি নির্দিষ্ট করার জন্য বৈশিষ্ট্য সিনট্যাক্সের পরিবর্তে আমাদের সম্পত্তি-উপাদান সিনট্যাক্স ব্যবহার করতে হবে, যা ভার্জোজ এবং জটিল ( আগের ব্লগ পোস্টে বাগ আরও ভাল )। এবং এই উভয় সীমাবদ্ধতা না থাকলেও আমি কেবল তাদের নাম ব্যবহার করে শৈলীর তালিকা লিখব - এটি প্রত্যেকের স্ট্যাটিক রিসোর্সের চেয়ে ছোট এবং সহজ পড়া is

সমাধানটি হ'ল কোড ব্যবহার করে একটি স্ট্যাটিক রিসোর্স এক্সটেনশন তৈরি করা। টাইপ স্ট্রিংয়ের একটি স্টাইল কী এবং একটি পরিষেবা সরবরাহকারীর দেওয়া, আমি প্রকৃত শৈলীর উদাহরণ পুনরুদ্ধার করতে স্ট্যাটিক রিসোর্সএক্সটেনশনটি ব্যবহার করতে পারি। এখানে বাক্য গঠন:

Style currentStyle = new StaticResourceExtension(currentResourceKey).ProvideValue(serviceProvider) as Style;

ProvideValue পদ্ধতিটি লেখার জন্য এখন আমাদের কাছে সমস্ত টুকরো রয়েছে:

public override object ProvideValue(IServiceProvider serviceProvider)
{
    Style resultStyle = new Style();

    foreach (string currentResourceKey in resourceKeys)
    {
        Style currentStyle = new StaticResourceExtension(currentResourceKey).ProvideValue(serviceProvider) as Style;

        if (currentStyle == null)
        {
            throw new InvalidOperationException("Could not find style with resource key " + currentResourceKey + ".");
        }

        resultStyle.Merge(currentStyle);
    }
    return resultStyle;
}

এখানে মাল্টিস্টাইল মার্কআপ এক্সটেনশনের ব্যবহারের সম্পূর্ণ উদাহরণ রয়েছে:

<Window.Resources>
    <Style TargetType="Button" x:Key="SmallButtonStyle">
        <Setter Property="Width" Value="120" />
        <Setter Property="Height" Value="25" />
        <Setter Property="FontSize" Value="12" />
    </Style>

    <Style TargetType="Button" x:Key="GreenButtonStyle">
        <Setter Property="Foreground" Value="Green" />
    </Style>

    <Style TargetType="Button" x:Key="BoldButtonStyle">
        <Setter Property="FontWeight" Value="Bold" />
    </Style>
</Window.Resources>

<Button Style="{local:MultiStyle SmallButtonStyle GreenButtonStyle BoldButtonStyle}" Content="Small, green, bold" />

এখানে চিত্র বর্ণনা লিখুন


3
সত্যিই ভাল সমাধান, তবে 3 বা + শৈলীর একত্রীকরণের কোনও সহজ সমাধান কেন হয় তা আমি বুঝতে পারি না।
মিঃ রুবিক্স

31

তবে আপনি অন্য থেকে প্রসারিত করতে পারেন .. ভিত্তিকভিত্তিক সম্পত্তিটি দেখুন

<Style TargetType="TextBlock">
      <Setter Property="Margin" Value="3" />
</Style>

<Style x:Key="AlwaysVerticalStyle" TargetType="TextBlock" 
       BasedOn="{StaticResource {x:Type TextBlock}}">
     <Setter Property="VerticalAlignment" Value="Top" />
</Style>

এটা আমার জন্য কল্পনা করা হয়েছিল। tnks!
ডেভিড লে

তবে এটি কেবল তখনই কাজ করে যদি উভয় শৈলী একই ধরণের হয় (এক্সএএমএল ত্রুটি: "লক্ষ্য ধরণের যে স্টাইলের ভিত্তি কেবল '<টাইপ>' টাইপ করা যায়)
ক্রিজিসটফ বোসিউরকো

17

ডাব্লুপিএফ / এক্সএএমএল স্থানীয়ভাবে এই কার্যকারিতা সরবরাহ করে না, তবে এটি আপনাকে যা করতে চায় তা করার অনুমতি দেওয়ার জন্য এটি এক্সটেনসিবিলিটি সরবরাহ করে।

আমরা একই প্রয়োজনে ছুটলাম, এবং আমাদের নিজস্ব দুটি এক্সএএমএল মার্কআপ এক্সটেনশন (যাকে আমরা "মার্জডস্টাইলস এক্সটেনশন" বলেছিলাম) তৈরি করে শেষ করেছিলাম যাতে আমাদের আরও দুটি স্টাইল (যা প্রয়োজনে সম্ভবত একাধিকবার ব্যবহার করা যেতে পারে) থেকে একটি নতুন স্টাইল তৈরি করতে দেয় to আরও বেশি শৈলী থেকে উত্তরাধিকারী হওয়ার জন্য সারি)।

ডাব্লুপিএফ / এক্সএএমএল বাগের কারণে এটি ব্যবহারের জন্য আমাদের সম্পত্তি উপাদান সিনট্যাক্স ব্যবহার করা দরকার, তবে এটি ঠিক আছে বলে মনে হচ্ছে। যেমন,

<Button
    Content="This is an example of a button using two merged styles">
    <Button.Style>
      <ext:MergedStyles
                BasedOn="{StaticResource FirstStyle}"
                MergeStyle="{StaticResource SecondStyle}"/>
   </Button.Style>
</Button>

আমি সম্প্রতি এটি সম্পর্কে এখানে লিখেছি: http://swdeveloper.wordpress.com/2009/01/03/wpf-xaml-m Multipleple-style-inheritance- and-markup-extensions/


3

আপনার স্টাইলগুলি ব্যবহার এবং মোড়ানোর জন্য কোনও সহায়ক শ্রেণি তৈরি করে এটি সম্ভব। এখানে উল্লিখিত কম্পাউন্ডস্টাইল এটি কীভাবে করবেন তা দেখায়। একাধিক উপায় রয়েছে তবে নিম্নলিখিতটি করা সবচেয়ে সহজ:

<TextBlock Text="Test"
    local:CompoundStyle.StyleKeys="headerStyle,textForMessageStyle,centeredStyle"/>

আশা করি এইটি কাজ করবে.


2

AttachedPropertyনিম্নলিখিত কোডের মতো একাধিক শৈলী সেট করতে ব্যবহার করুন :

public class Css
{

    public static string GetClass(DependencyObject element)
    {
        if (element == null)
            throw new ArgumentNullException("element");

        return (string)element.GetValue(ClassProperty);
    }

    public static void SetClass(DependencyObject element, string value)
    {
        if (element == null)
            throw new ArgumentNullException("element");

        element.SetValue(ClassProperty, value);
    }


    public static readonly DependencyProperty ClassProperty =
        DependencyProperty.RegisterAttached("Class", typeof(string), typeof(Css), 
            new PropertyMetadata(null, OnClassChanged));

    private static void OnClassChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var ui = d as FrameworkElement;
        Style newStyle = new Style();

        if (e.NewValue != null)
        {
            var names = e.NewValue as string;
            var arr = names.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var name in arr)
            {
                Style style = ui.FindResource(name) as Style;
                foreach (var setter in style.Setters)
                {
                    newStyle.Setters.Add(setter);
                }
                foreach (var trigger in style.Triggers)
                {
                    newStyle.Triggers.Add(trigger);
                }
            }
        }
        ui.Style = newStyle;
    }
}

Usege:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:style_a_class_like_css"
        mc:Ignorable="d"
        Title="MainWindow" Height="150" Width="325">
    <Window.Resources>

        <Style TargetType="TextBlock" x:Key="Red" >
            <Setter Property="Foreground" Value="Red"/>
        </Style>

        <Style TargetType="TextBlock" x:Key="Green" >
            <Setter Property="Foreground" Value="Green"/>
        </Style>

        <Style TargetType="TextBlock" x:Key="Size18" >
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="Margin" Value="6"/>
        </Style>

        <Style TargetType="TextBlock" x:Key="Bold" >
            <Setter Property="FontWeight" Value="Bold"/>
        </Style>

    </Window.Resources>
    <StackPanel>

        <Button Content="Button" local:Css.Class="Red Bold" Width="75"/>
        <Button Content="Button" local:Css.Class="Red Size18" Width="75"/>
        <Button Content="Button" local:Css.Class="Green Size18 Bold" Width="75"/>

    </StackPanel>
</Window>

ফলাফল:

এখানে চিত্র বর্ণনা লিখুন


1

আপনি যদি কোনও নির্দিষ্ট বৈশিষ্ট্য স্পর্শ না করে থাকেন তবে আপনি সমস্ত বেস এবং সাধারণ বৈশিষ্ট্যগুলি স্টাইলটিতে পেতে পারেন যার লক্ষ্য প্রকারের ফ্রেমওয়ার্কএলমেন্ট। তারপরে, আপনি সেই সমস্ত সাধারণ বৈশিষ্ট্য আবার অনুলিপি না করে আপনার প্রয়োজনীয় প্রতিটি টার্গেটের জন্য নির্দিষ্ট স্বাদ তৈরি করতে পারেন।


1

আপনি যদি স্টাইলসিলেক্টর ব্যবহার করে আইটেমগুলির সংকলনে এটি প্রয়োগ করে থাকেন তবে সম্ভবত আপনি অনুরূপ কিছু পেতে পারেন, আমি গাছের মধ্যে আবদ্ধ অবজেক্টের ধরণের উপর নির্ভর করে TreeViewItems এ বিভিন্ন স্টাইল ব্যবহার করার ক্ষেত্রে একই ধরণের সমস্যার সাথে যোগাযোগ করতে এটি ব্যবহার করেছি। আপনার নির্দিষ্ট পদ্ধতির সাথে সামঞ্জস্য করতে আপনাকে নীচের শ্রেণিটি কিছুটা সংশোধন করতে হতে পারে তবে আশা করি এটি আপনাকে শুরু করবে

public class MyTreeStyleSelector : StyleSelector
{
    public Style DefaultStyle
    {
        get;
        set;
    }

    public Style NewStyle
    {
        get;
        set;
    }

    public override Style SelectStyle(object item, DependencyObject container)
    {
        ItemsControl ctrl = ItemsControl.ItemsControlFromItemContainer(container);

        //apply to only the first element in the container (new node)
        if (item == ctrl.Items[0])
        {
            return NewStyle;
        }
        else
        {
            //otherwise use the default style
            return DefaultStyle;
        }
    }
}

আপনি তারপরে এটি প্রয়োগ করুন

 <ট্রিভিউ>
     <TreeView.ItemContainerStyleSelector
         <মায়াস্যাসাবলিউশন: মাইটিস্ট্রাইলসাইলেক্টর ডিফল্ট স্টাইল = "{স্ট্যাটিক রিসোর্স ডিফল্ট আইটেম স্টাইল}"
                                         নিউ স্টাইল = "{স্ট্যাটিক রিসোর্স নিউ আইটেম স্টাইল}" />
     </TreeView.ItemContainerStyleSelector>
  </ ট্রিভিউ>

1

কখনও কখনও আপনি বাসা প্যানেল দ্বারা এটি যোগাযোগ করতে পারেন। বলুন আপনার একটি স্টাইল রয়েছে যা ফোরগ্রাউন্ড এবং অন্য একটি ফন্টসাইজ পরিবর্তন করে, আপনি পরবর্তীটি একটি টেক্সটব্লকটিতে প্রয়োগ করতে পারেন এবং গ্রিডে রাখতে পারেন যা এর স্টাইলটি প্রথম। এটি কিছু ক্ষেত্রে সবচেয়ে সহজ উপায় হতে পারে এবং যদিও এটি সমস্ত সমস্যার সমাধান করবে না।


1

আপনি যখন সিলেক্ট স্টাইলকে ওভাররাইড করবেন আপনি নীচের মত প্রতিচ্ছবি মাধ্যমে গ্রুপপাই সম্পত্তি পেতে পারেন:

    public override Style SelectStyle(object item, DependencyObject container)
    {

        PropertyInfo p = item.GetType().GetProperty("GroupBy", BindingFlags.NonPublic | BindingFlags.Instance);

        PropertyGroupDescription propertyGroupDescription = (PropertyGroupDescription)p.GetValue(item);

        if (propertyGroupDescription != null && propertyGroupDescription.PropertyName == "Title" )
        {
            return this.TitleStyle;
        }

        if (propertyGroupDescription != null && propertyGroupDescription.PropertyName == "Date")
        {
            return this.DateStyle;
        }

        return null;
    }

0

আপনি যদি কেবল একটি একক উপাদানে একটি অনন্য শৈলী প্রয়োগ করার চেষ্টা করছেন বেস শৈলীর সংযোজন হিসাবে , এটি করার সম্পূর্ণ ভিন্ন উপায় রয়েছে যা পাঠযোগ্য ও রক্ষণাবেক্ষণযোগ্য কোডের জন্য IMHO better

পৃথক উপাদান অনুসারে প্যারামিটারগুলি টুইঙ্ক করা খুব সাধারণ। কেবলমাত্র এক-উপাদানটিতে ব্যবহারের জন্য অভিধানের শৈলীর সংজ্ঞা দেওয়া বা বজায় রাখতে বা বোঝার জন্য অত্যন্ত জটিল। কেবল এক-অফ এলিমেন্ট টুইটের জন্য শৈলী তৈরি করা এড়াতে, এখানে আমার নিজের প্রশ্নের আমার উত্তরটি এখানে পড়ুন:

https://stackoverflow.com/a/54497665/1402498

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.